总结一下java8中的新特性内置的四大核心函数式接口
函数式接口在java中是指:有且仅有一个抽象方法的接口
函数式接口,即适用于函数式编程场景的接口。而java中的函数式编程体现就是Lambda,所以函数式接口就是可以适用于Lambda使用的接口。只有确保接口中有且仅有一个抽象方法,Java中的Lambda才能顺利地进行推导。
@FunctionalInterface @FunctionalInterface标注在一个接口上,说明这个接口是一个函数式接口。
那么关于函数式接口,有如下特点:
有且只有一个抽象方法
可以有多个静态方法
可以有多个default方法(默认方法)
可以有多个Object的public的抽象方法
消费型接口Consumer: 源码
1 2 3 4 5 6 7 8 9 @FunctionalInterface public interface Consumer <T> { void accept (T t) ; default Consumer<T> andThen (Consumer<? super T> after) { Objects.requireNonNull(after); return (T t) -> { accept(t); after.accept(t); }; } }
Consumer有参数,无返回值
Consumer有两个方法:accept()抽象方法, andThen()非抽象方法
使用示例:
1 2 3 4 5 6 7 8 9 @Test public void test1 () { happy(10000 , (m) -> System.out.println("消费:" + m + "元" )); } public void happy (double money, Consumer<Double> con) { con.accept(money); }
供给型接口Supplier: 源码
1 2 3 4 5 @FunctionalInterface public interface Supplier <T> { T get () ; }
使用示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 @Test public void test2 () { List<Integer> numList = getNumList(10 , () -> (int )(Math.random() * 100 )); for (Integer num : numList) { System.out.println(num); } } public List<Integer> getNumList (int num, Supplier<Integer> sup) { List<Integer> list = new ArrayList <>(); for (int i = 0 ; i < num; i++) { Integer n = sup.get(); list.add(n); } return list; }
函数型接口Function: 源码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 @FunctionalInterface public interface Function <T, R> { R apply (T t) ; default <V> Function<V, R> compose (Function<? super V, ? extends T> before) { Objects.requireNonNull(before); return (V v) -> apply(before.apply(v)); } default <V> Function<T, V> andThen (Function<? super R, ? extends V> after) { Objects.requireNonNull(after); return (T t) -> after.apply(apply(t)); } static <T> Function<T, T> identity () { return t -> t; } }
使用示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 @Test public void test3 () { String newStr = strHandler("\t\t\t 这是一个字符串" , (str) -> str.trim()); System.out.println(newStr); String subStr = strHandler("这是一个字符串" , (str) -> str.substring(2 , 5 )); System.out.println(subStr); } public String strHandler (String str, Function<String, String> fun) { return fun.apply(str); }
断言型接口:Predicate 源码:
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 @FunctionalInterface public interface Predicate <T> { boolean test (T t) ; default Predicate<T> and (Predicate<? super T> other) { Objects.requireNonNull(other); return (t) -> test(t) && other.test(t); } default Predicate<T> negate () { return (t) -> !test(t); } default Predicate<T> or (Predicate<? super T> other) { Objects.requireNonNull(other); return (t) -> test(t) || other.test(t); } static <T> Predicate<T> isEqual (Object targetRef) { return (null == targetRef) ? Objects::isNull : object -> targetRef.equals(object); } }
Predicate默认实现的三个重要方法and,or和negate,这三个方法对应了java的三个连接符号&&、||和!,isEqual这个方法的返回类型也是Predicate,所以我们也可以把它作为函数式接口进行使用。我们可以当做==操作符来使用。
使用示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 @Test public void test4 () { List<String> list = Arrays.asList("Hello" , "atguigu" , "Lambda" , "www" , "ok" ); List<String> strList = filterStr(list, (s) -> s.length() > 3 ); for (String str : strList) { System.out.println(str); } } public List<String> filterStr (List<String> list, Predicate<String> pre) { List<String> strList = new ArrayList <>(); for (String str : list) { if (pre.test(str)){ strList.add(str); } } return strList; }