lambda表达式是一个可传递的代码块,以及必须传入代码的变量规范。
形式:参数 () 箭头 -> 表达式 {....}
如果可以推导出一个lambda表达式的参数类型,则可以忽略器类型:
Comparator<String> comp = (first, second) -> first.length() - second.length();
编译器可以推导出first、second必然是字符串,因为这个lambda表达式将赋给一个字符串比较器
如果方法只有一个参数,而且这个参数的类型可以推导得出,那么甚至还可以省略小括号:
ActionListen listener = event -> System.out.println("the time is " + new Data()");
无需指定lambda表达式的返回类型,
其总是会由上下文推导得出。
如果一个lambda表达式只在某些分支返回一个值,而在另外一些分支不返回值,这是不合法的
例如:
(int x) -> {if(x>=0) return 1;} 就不合法
1.函数式接口:对于只有一个抽象方法的接口,需要这种接口的对象时,就可以提供一个lambda表达式。这种接口称为函数式接口。
2.方法引用:主要有三种情况:object::instanceMethod; Class::staticMethod; Class::instanceMethod.
3.构造器引用:与方法引用类似,只不过方法名为new。例如,Person::new是Person构造器的一个引用
ArrayList<String> names = ...;
Stream<Person> stream = names.stream().map(Person::new);
List<Person> people = stream.collect(Collectors.toList());
java有一个限制,无法构造泛型类型T的数组。数组构造器引用对于克服这个限制很有用。表达式new T[n]会产生错误,因为这会改为new Object[n]。
Object[] people = stream.toArray();
要得到Person引用数组,而不是Object[]引用数组
Person[] people = stream.toArray(Person[]::new);
4.处理lambda表达式
repeat(10, () -> System.out.println("hello world!"))
public static void repeat(int n, Runnable action) {
for (int i=0; i<n; i++) action.run();
}
Runnable就是常用的函数式接口之一。