什么是函数式(Functional
)接口
只包含一个抽象方法的接口,称为函数式接口
你可以通过 Lambda
表达式来创建接口的对象。(若 Lambda
表达式抛出一个受检异常 – 即:非运行时异常,那么该异常需要在目标接口的抽象方法上进行声明)。
我们可以在一个接口上使用 @FunctionalInterface
注解,这样做可以检查它是否是一个函数式接口。同时 javadoc
也会包含一条声明,说明这个借口是一个函数式接口。
在 java.util.function
包下定义了 Java 8 的丰富的函数式接口
自定义函数
示例一:
1 2 3 4 @FunctionalInterface public interface MyNumber { public double getValue () ; }
示例二:(函数式接口中使用泛型)
1 2 3 4 @FunctionalInterface public interface MyFunction <T > { public T getValue (T t) ; }
作为参数传递Lambda表达式
示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 public String strHandler (String str, MyFunction<String> mf) { return mf.getValue(str); } @Test public void m () { String handler = strHandler("帅是没有道理的 " , new MyFunction<String>() { @Override public String getValue (String s) { return s.trim(); } }); System.out.println(handler); String trimStr = strHandler("帅是没有道理的 " , str -> str.trim()); System.out.println(trimStr); String upperStr = strHandler("abcdefg" , (str) -> str.toUpperCase()); System.out.println(upperStr); String newStr = strHandler("have a good night" , (str) -> str.substring(2 , 5 )); System.out.println(newStr); }
作为参数传递 Lambda
表达式:为了将 Lambda
表达式作为参数传递,接收 Lambda
表达式的参数类型必须是与该 Lambda
表达式兼容的函数式接口的类型。
Java 内置四大核心函数式接口
在学习 lambda
表达式的时候,我们知道,要使用 lambda
表达式,我们就要创建一个函数式接口,那每次用 lambda
表达式的时候岂不是很麻烦,这时候,Java 给我们内置了四大核心函数式接口。
还有一些其他接口
四大接口示例
Consumer<T>
:消费型接口,void accept(T t)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 @Test public void m1 () { happyTime(500 , new Consumer<Double>() { @Override public void accept (Double aDouble) { System.out.println("学习太累,去上人间买了瓶矿泉水,价格为:" + aDouble); } }); happyTime(500 , money -> System.out.println("学习太累,去天上人间买了瓶矿泉水,价格为:" + money)); } public void happyTime (double money, Consumer<Double> consumer) { consumer.accept(money); }
Supplier<T>
:供给型接口,T get()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 @Test public void m3 () { List<Integer> numList = getNumList(10 , new Supplier<Integer>() { @Override public Integer get () { return (int ) (Math.random() * 100 ); } }); System.out.println(numList); List<Integer> numListL = getNumList(10 , () -> (int ) (Math.random() * 100 )); System.out.println(numListL); } public List<Integer> getNumList (int num, Supplier<Integer> supplier) { List<Integer> arrayList = new ArrayList<>(); for (int i = 0 ; i < num; i++) { Integer n = supplier.get(); arrayList.add(n); } return arrayList; }
Function<T, R>
:函数型接口,R apply(T t)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 @Test public void m4 () { String s = sHandler("\t\t Vincent帅到掉渣... " , new Function<String, String>() { @Override public String apply (String s) { return s.trim(); } }); System.out.println(s); String sL = strHandler("\t\t Vincent帅到掉渣... " , str -> str.trim()); System.out.println(sL); } public String sHandler (String str, Function<String, String> function) { return function.apply(str); }
Predicate<T>
:断言型接口,boolean test(T t)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 @Test public void m2 () { List<String> list = Arrays.asList("北京" , "南京" , "天津" , "东京" , "西京" , "普京" ); List<String> filterStrs = filterString(list, new Predicate<String>() { @Override public boolean test (String s) { return s.contains("京" ); } }); System.out.println(filterStrs); List<String> filterStrsL = filterString(list, s -> s.contains("京" )); System.out.println(filterStrsL); } public List<String> filterString (List<String> list, Predicate<String> predicate) { ArrayList<String> filterList = new ArrayList<>(); for (String s : list) { if (predicate.test(s)) { filterList.add(s); } } return filterList; }
案例源码:https://github.com/V-Vincen/jdk_18
If you like this blog or find it useful for you, you are welcome to comment on it. You are also welcome to share this blog, so that more people can participate in it. If the images used in the blog infringe your copyright, please contact the author to delete them. Thank you !