java.util.function.Function<T, R>是一个含有多个默认方法的函数式接口,抽象方法为:(T t) ->R。看下代码,你就懂了~
@FunctionalInterface public interface Function<T, R> { //接口方法,入参为泛型T,返回泛型R。即:(T t) -> R R apply(T t); //默认方法,实现级联操作。before方法输入V,输出T,本function输入T,输出R。 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; }
在处理数据时,使用特定方法,可以避免装箱操作,如:IntPredicate、LongConsumer、DoubleFunction等。具体见API库。
总结
函数描述符 | 函数式接口 |
---|---|
(T) ->bool | java.util.function.Predicate<T> |
(T) -> void | java.util.function.Consumer<T> |
(T) -> R | java.util.function.Function<T, R> |
(T,U) -> R | java.util.function.BiFunction<T, U, R> |
() -> T | java.util.function.Supplier<T> |
只要函数描述符兼容,函数式接口就可以复用。
特殊的void兼容规则:
// Predicate返回了一个boolean Predicate<String> p = s -> list.add(s); // Consumer返回了一个void Consumer<String> b = s -> list.add(s);
方法引用是调用单一方法的Lambda的快捷写法,格式ClassName::methodName。看下栗子你就懂了~
一般方法引用
(Apple a) -> a.getWeight() 等价于Apple::getWeight () -> Thread.currentThread().dumpStack() 等价于 Thread.currentThread()::dumpStack (str, i) -> str.substring(i) 等价于 String::substring (String s) -> System.out.println(s) 等价于 System.out::println (list, element) -> list.contains(element) 等价于 List::contains
主要有三类:
指向静态方法的方法引用,如:Integer::parseInt 指向任意类型实例方法的方法引用,如:String::length 指向现有对象的实例方法的方法引用,如:User::getUserId构造函数引用
无参构造函数
无参构造函数的函数描述符:() -> T,由上面的总结知,可以使用Supplier接口,如下:
Supplier<User> c1 = User::new; // c1 = () -> new User(); User user = c1.get();
有一个参数的构造函数