说到函数式编程,首先想到的就是lambda表达式和方法引用
lambda表达式可以直接用在,只定义了单方法的接口(FunctionalInterface)上
编译器自动识别出传入参数(s1,s2)的类型和返回值类型,免去了复杂的匿名类实现
Arrays.sort(array, (s1, s2) -> {
return s1.compareTo(s2);
});
方法引用只要当某个方法签名和接口恰好一致(方法参数一致,返回类型相同),就可以直接把方法名作lombda表达式传入
String[] array = new String[] { "Apple", "Orange", "Banana", "Lemon" };
Arrays.sort(array, Main::cmp);
Arrays.sort(array, String::compareTo);
List<Person> persons = array.stream().map(Person::new).collect(Collectors.toList());
static int cmp(String s1, String s2) {
return s1.compareTo(s2);
}
可以传入静态方法,实例方法,构造方法
传入实例方法时,实例类型被看做第一个参数类型
public final class String {
public int compareTo(String o) {
...
}
}
因为实例方法有一个隐含的this
参数,String
类的compareTo()
方法在实际调用的时候,第一个隐含参数总是传入this
相当于静态方法:
public static int compareTo(this, String o);
传入构造方法时,实例类型被看做返回类型
map()
需要传入的FunctionalInterface的定义是
@FunctionalInterface
public interface Function<T, R> {
R apply(T t);
}
了解了lombda表达式与方法引用后,就可以来了解java.util.function包
接口 | 描述 |
---|---|
Predicate//谓词 | 接收一个传入参数,返回一个boolean |
Function<T,R>//功能 | 接受一个输入参数,返回一个结果 |
Supplier//供给 | 无参数,返回一个结果 |
Consumer//消费 | 接受一个输入参数,并且不返回任何结果 |
BiFunction<T,U,R> | 接受两个输入参数的方法,并且返回一个结果 |
BiConsumer<T,U> | 接受两个输入参数的操作,并且不返回任何结果 |
其实就是普通的接口,通过实现,lambda等方式实现后,根据签名一致性,像普通实例一样调用。可参考: