lambda
1. 什么是lambda
iamdba是在java中一个可传递的代码块,一般用于代替接口方法实现。
因为java是一个面向对象的语言,所以代码块一般都存放在类中,要想调用代码块,必须先创建一个对象来进行调用在类中的代码块。所以我们可以使用lamdba来避免创建对象的麻烦和提高代码的可读性。
2.lambda的语法
(参数)->表达式or{方法+return }
例:
(String first,String second)
-> first.length() - second.length
//or
(String first,String second)
->{
if(first.length()<second.length())
return -1;
else
return 0;
}
注意:若无参数,也要保留()
3.用lambda实现函数式接口
对于只有一个抽象方法的接口,需要这种接口的对象时,就可以提供一个lambda表达式。这种接口称为函数式接口。
例:
Arrays.sort方法的第二个参数需要一个Comparator实例,而Comparator就是只有一个方法的接口。原本我们应该这样写代码:
//创建一个类来实现接口Comparator的抽象方法
class LengthComparator implements Comparator<String>
{
public int compare(String first,String second)
{
return first.length()-second.length();
}
}
...
//在第二个参数中new这个类来调用方法
Arrays.sort(strings,new LengthComparator());
但是我们可以用lambda表达式来替换类的实现和使用new来调用方法:
Arrays.sort(a,(first,second)->first.length() - second.length());
//在这里编译器可以推导出first和second必然是字符串,还有return的必然是int所以可以省略String和return
在上面的例子中,我们就使用了lambda表达式来替换了麻烦的创建类并通过new对象来调用代码块。使用lambda表达式直接写出接口的实现代码块大大增加了代码的可读性。
方法引用
方法引用会指示编译器生成一个函数式接口的实例,覆盖这个接口的抽象方法来调用给定的方法。
类似于lambda表达式,方法引用也不是对象。不过为一个类型为函数式接口的变量赋值时会生成一个对象。<不是对象,但会生成对象>
例:
Array.sort(strings , String::compareToIgnorreCase);
语法:
用::运算符分割方法名与对象或类名。
3种情况:
1.object::instanceMethod
2.Class::instanceMethod
3.Class::staticMethod
第一种情况:例如对象是System.out,System::println等价于x->System.out.println(x)。
第二种情况:第一个参数会成为方法的隐式参数。String::compareToIgnoreCase等价于(x,y)->x.compareToIgnoreCase(y)。
第三种情况:所有参数都传到静态方法:Math::pow等价于(x,y)->Math.pow(x,y)。
构造器引用
与方法引用类似,只不过将方法改成了new,变成了 …::new
int[]::new等价于x->new int[x]。
例:用户希望得到一个Person引用数组
Person[] people=stream.toArray(Person[]::new);
变量作用域
在lambda表达式中,只能引用值不会发生改变的变量。也就是说,表达式捕获的变量必须是事实最终变量–这个变量在初始化之后就不会再为他赋新值。