目录
为什么要用lambda表达式?
与其说它是新功能,不如说它更像是一种编码风格。
①简洁。显而易见,也是最重要的一点。
②非常容易并行计算。还是因为用lambda写的线程代码很简洁。
③递归运算非常快,java有针对递归的专门优化。
lambda表达式的各个部分都代表什么?
看一个可运行的含有lambda的代码
public class LaTest {
public static void main(String[] args) {
new Thread(() -> System.out.println("helloworld")).start();
}
}
分离出lambda表达式进行详解
new Thread(() -> System.out.println("helloworld")).start();
进一步分离并抽象
( parameter-list ) -> { expression-or-statements }
'->',只要含有它就表示这是一个lambda表达式
'->'前面的'()'用来传参数的,只不过这个例子中Thread中的run方法不用参数
'->'后面的是重写的run方法的代码
lambda中的方法没有方法名,怎么知道用的哪个方法?
lambda实现接口中的方法时,这个接口只有一个方法,如果你用了多个方法会在编译时报错。
我建立了一个可以使用lambda表达式的接口@FunctionalInterface就是告诉编译器
可以用lambda表达式。
@FunctionalInterface
public interface ITest {//报错
public void zeroparam();
public void oneparam(int a);
public void twoparam(int a,int b);
}
错误:Multiple non-overriding abstract methods found in interface ITest
翻译: 在接口ITest中找到多个非重写抽象方法
(a)->{}和(int a)->{}有什么区别吗?
本质上没有区别,前者虽然没有指明参数类型,但是编译器会自动去找的。
这也容易让刚学lambda的同学误认为()中要传一个具体的参数,我就误认为了。题干中的表达式的本质是对接口方法的重写。
lambda表达式可以用来完成哪些基本操作?
①为变量赋值操作和返回返回值操作。
@FunctionalInterface
public interface ITest {
public int oneparam(int a);
}
public static void main(String arg[]){
ITest test= //为变量test赋值
(int a)->{
System.out.println(a);
return a;
};
int output=test.oneparam(123);//可以返回返回值。
System.out.println(output);
}
②作为数组元素
ITest test2[]={
(int b)->{return b;},
(int b)->{return b+b;}
};
它返回的是数组,数组元素是两个实例。
好处是,对于一个类,我在实现方法上很多的选择,而且代码更简单。
如果不用lambda就会代码非常混乱。
ITest test2[]={
new ITest() {
@Override
public int oneparam(int a) {
return a;
}
},
new ITest() {
@Override
public int oneparam(int a) {
return a+a;
}
}
};
才两个元素就已经这个样子了,多一点代码没法看了。
为什么我在lambda中使用外部变量会编译报错?
public static void main(String arg[]){
int output=0;
ITest test= (a)->{output=1; return output;};
}
报错:Variable used in lambda expression should be final or effectively final
翻译:lambda表达式中使用的变量应为final或 effectively final
lambda 表达式的局部变量可以不用声明为 final,但是必须不可被后面的代码修改(即隐性的具有 final 的语义)
如果在要是用的局部变量上final就可以了。
如果想在lambda中使用外部变量怎么办?
下面的代码展示了三种方式。①修改static的全局变量;②修改类中的变量;③修改数组中的元素
static int output=0;
public static void main(String arg[]){
class OneNums{
private int n=0;
public int getN() { return n;}
public void setN(int n) {this.n = n;}
}
int arr[]={1};
OneNums oneNums=new OneNums();
//①修改static的全局变量;
ITest test= (a)->{output=2; return 0;};
test.oneparam(0);
System.out.println(output);
//②修改类中的变量;
ITest test2= (a)->{arr[0]=2; return 0;};
test2.oneparam(0);
System.out.println(arr[0]);
//③修改数组中的元素
ITest test3=(a)->{oneNums.setN(2);return 0;};
test3.oneparam(0);
System.out.println(oneNums.getN());
}
我私下里总结一下,感觉lambda无法直接修改存放在栈中的变量,可以修改在堆中的变量。lambda不能修改引用,但可以修改引用指向的那块地址中的数据。
好了,如果说错了什么,大家可以骂我了。
我一定要用多多使用lambda表达式编程吗?
建议不要为了秀操作而使用lambda,玩王者荣耀时,用公孙离秀出花来也可能打不过后羿伽罗这种站撸型英雄。要结合具体项目情况,能否使代码简洁易懂发挥lambda的优势,利用战场环境击杀对手。乱秀操作,队友看不懂你在干嘛。