lambda表达式
java中的lambda表达式简单理解就是一个代码块,同时规范了传入代码的输入变量。
- 多参的lambda表达式
//int[] data={3,2,1};
Integer[] data={3,2,1};
Arrays.sort(data,(a,b)-> a-b);
System.out.println(Arrays.toString(data));
- 单参的lambda表达式
(x)->System.out.println(x)//right
x->System.out.println(x)//right
- 无参的lambda表达式
()->System.out.println("Hello,world.")
lambda表达式的使用环境
对于只有一种抽象方法的接口(函数式接口),需要这种接口的对象时(实际上,依然是想通过这个结果调用接口中的方法),就可以提供一个lambda表达式。例如:
public interface Comparator<T>{
...
int compare(T o1, T o2);
}
方法引用与lambda表达式
方法引用主要有以下3种情况:
- object::instanceMethod
- Class::staticMethod
- Class::instanceMethod
前面两种情况较好理解,等价于提供方法参数的lambda表达式。例如
System.out::println//使用方法引用的版本
x->System.out.println(x)//一般的lambda表达式
Math::pow
(x,y)->Math.pow(x,y)
对于第三种情况,第一个参数会成为调用方法的实例对象
String::compareToIgnoreCase
(x,y)->x.compareToIgnoreCase(y)
当然,这里依然涉及到编译器对于重载函数版本的解析。
此外是this,super关键字在方法引用中的使用,如:
this::toString
()->this.toString()
super::equals
x->super.equals(x)
这个实际上属于第一种方法引用的情况。
lambda表达式的理解
有时候lambda表达式的代码逻辑中还涉及到使用外围的变量,对于lambda表达式而言,就是自由变量,为了防止这种变量在lambda表达式运行的时候生命周期已经结束,lambda表达式会存储自由变量的值,即所谓的capture,这里要注意,如果自由变量在运行期间发生改变(无论是在lambda表达式内部,还是在外部),并发执行就会不安全。因此,lambda表达式中捕获的自由变量不再修改。
最后,lambda的this关键字指的是创建lambda表达式方法的实例。
运行lambda表达式
lambda表达式的运行需要通过函数式接口来实现,例如:
//example 1
public class LambdaRunner{
//example 1
public static void repeat(int n,Runnable action){
for(int i=0;i<n;i++)
action.run();
}
//example 2
public static void repeat(int n,IntConsumer action){
for(int i=0;i<n;i++)
action.accept(i);
}
public static void main(String[] args){
repeat(3,()->System.out.println("Hello,world!"));
repeat(3, x->System.out.println("Counter: "+x));
}
}
interface IntConsumer{
void accept(int value);
}