一文带你入门JDK8新特性——Lambda表达式
Lambda简介
Lambda表达式是JDK8的一个新特性,可以取代大部分的匿名内部类,写出更优雅的Java代码,尤其在集合的遍历和其他集合操作中,可以极大地优化代码结构。
JDK也提供了大量的内置函数式接口供我们使用,使得Lambda表达式的运用更加方便、高效。
对接口的要求
虽然使用Lambda表达式可以对某些接口进行简单的实现,但并不是所有的接口都可以使用Lambda表达式来实现。Lambda规定接口中只能有一个需要被实现的方法,不是规定接口中只能有一个方法
jdk8中有另一个新特性:default,被default修饰的方法会有默认实现,不是必须被实现的方法,所以不影响Lambda表达式的使用。
@FunctionalInterface
修饰函数式接口的,要求接口中的抽象方法只有一个。这个注解往往会和lambda表达式一起出现。
Lambda基础语法
我们这里给出六个接口,后文的全部操作都利用这六个接口来进行阐述。
/**多参数无返回*/ @FunctionalInterface publicinterfaceNoReturnMultiParam{ voidmethod(inta,intb); } /**无参无返回值*/ @FunctionalInterface publicinterfaceNoReturnNoParam{ voidmethod(); } /**一个参数无返回*/ @FunctionalInterface publicinterfaceNoReturnOneParam{ voidmethod(inta); } /**多个参数有返回值*/ @FunctionalInterface publicinterfaceReturnMultiParam{ intmethod(inta,intb); } /***无参有返回*/ @FunctionalInterface publicinterfaceReturnNoParam{ intmethod(); } /**一个参数有返回值*/ @FunctionalInterface publicinterfaceReturnOneParam{ intmethod(inta); }
语法形式为()->{},其中()用来描述参数列表,{}用来描述方法体,->为lambda运算符,读作(goesto)。
importlambda.interfaces.*; publicclassTest1{ publicstaticvoidmain(String[]args){ //无参无返回 NoReturnNoParamnoReturnNoParam=()->{ System.out.println("NoReturnNoParam"); }; noReturnNoParam.method(); //一个参数无返回 NoReturnOneParamnoReturnOneParam=(inta)->{ System.out.println("NoReturnOneParamparam:"+a); }; noReturnOneParam.method(6); //多个参数无返回 NoReturnMultiParamnoReturnMultiParam=(inta,intb)->{ System.out.println("NoReturnMultiParamparam:"+"{"+a+","++b+"}"); }; noReturnMultiParam.method(6,8); //无参有返回值 ReturnNoParamreturnNoParam=()->{ System.out.print("ReturnNoParam"); return1; }; intres=returnNoParam.method(); System.out.println("return:"+res); //一个参数有返回值 ReturnOneParamreturnOneParam=(inta)->{ System.out.println("ReturnOneParamparam:"+a); return1; }; intres2=returnOneParam.method(6); System.out.println("return:"+res2); //多个参数有返回值 ReturnMultiParamreturnMultiParam=(inta,intb)->{ System.out.println("ReturnMultiParamparam:"+"{"+a+","+b+"}"); return1; }; intres3=returnMultiParam.method(6,8); System.out.println("return:"+res3); } }
Lambda语法简化
我们可以通过观察以下代码来完成代码的进一步简化,写出更加优雅的代码。
importlambda.interfaces.*; publicclassTest2{ publicstaticvoidmain(String[]args){ //1.简化参数类型,可以不写参数类型,但是必须所有参数都不写 NoReturnMultiParamlamdba1=(a,b)->{ System.out.println("简化参数类型"); }; lamdba1.method(1,2); //2.简化参数小括号,如果只有一个参数则可以省略参数小括号 NoReturnOneParamlambda2=a->{ System.out.println("简化参数小括号"); }; lambda2.method(1); //3.简化方法体大括号,如果方法条只有一条语句,则可以胜率方法体大括号 NoReturnNoParamlambda3=()->System.out.println("简化方法体大括号"); lambda3.method(); //4.如果方法体只有一条语句,并且是return语句,则可以省略方法体大括号 ReturnOneParamlambda4=a->a+3; System.out.println(lambda4.method(5)); ReturnMultiParamlambda5=(a,b)->a+b; System.out.println(lambda5.method(1,1)); } }
Lambda表达式常用示例
lambda表达式引用方法
有时候我们不是必须要自己重写某个匿名内部类的方法,我们可以可以利用lambda表达式的接口快速指向一个已经被实现的方法。
语法
方法归属者::方法名静态方法的归属者为类名,普通方法归属者为对象
publicclassExe1{ publicstaticvoidmain(String[]args){ ReturnOneParamlambda1=a->doubleNum(a); System.out.println(lambda1.method(3)); //lambda2引用了已经实现的doubleNum方法 ReturnOneParamlambda2=Exe1::doubleNum; System.out.println(lambda2.method(3)); Exe1exe=newExe1(); //lambda4引用了已经实现的addTwo方法 ReturnOneParamlambda4=exe::addTwo; System.out.println(lambda4.method(2)); } /** *要求 *1.参数数量和类型要与接口中定义的一致 *2.返回值类型要与接口中定义的一致 */ publicstaticintdoubleNum(inta){ returna*2; } publicintaddTwo(inta){ returna+2; } }
构造方法的引用
一般我们需要声明接口,该接口作为对象的生成器,通过类名::new的方式来实例化对象,然后调用方法返回对象。
interfaceItemCreatorBlankConstruct{ ItemgetItem(); } interfaceItemCreatorParamContruct{ ItemgetItem(intid,Stringname,doubleprice); } publicclassExe2{ publicstaticvoidmain(String[]args){ ItemCreatorBlankConstructcreator=()->newItem(); Itemitem=creator.getItem(); ItemCreatorBlankConstructcreator2=Item::new; Itemitem2=creator2.getItem(); ItemCreatorParamContructcreator3=Item::new; Itemitem3=creator3.getItem(112,"鼠标",135.99); } }
lambda表达式创建线程
我们以往都是通过创建Thread对象,然后通过匿名内部类重写run()方法,一提到匿名内部类我们就应该想到可以使用lambda表达式来简化线程的创建过程。
Threadt=newThread(()->{ for(inti=0;i<10;i++){ System.out.println(2+":"+i); } }); t.start();
遍历集合
我们可以调用集合的publicvoidforEach(Consumeraction)方法,通过lambda表达式的方式遍历集合中的元素。以下是Consumer接口的方法以及遍历集合的操作。Consumer接口是jdk为我们提供的一个函数式接口。
@FunctionalInterface publicinterfaceConsumer{ voidaccept(Tt); //.... } ArrayList list=newArrayList<>(); Collections.addAll(list,1,2,3,4,5); //lambda表达式方法引用 list.forEach(System.out::println); list.forEach(element->{ if(element%2==0){ System.out.println(element); } });
删除集合中的某个元素
我们通过publicbooleanremoveIf(Predicatefilter)方法来删除集合中的某个元素,Predicate也是jdk为我们提供的一个函数式接口,可以简化程序的编写。
ArrayList- items=newArrayList<>(); items.add(newItem(11,"小牙刷",12.05)); items.add(newItem(5,"日本马桶盖",999.05)); items.add(newItem(7,"格力空调",888.88)); items.add(newItem(17,"肥皂",2.00)); items.add(newItem(9,"冰箱",4200.00)); items.removeIf(ele->ele.getId()==7); //通过foreach遍历,查看是否已经删除 items.forEach(System.out::println);
集合内元素的排序
在以前我们若要为集合内的元素排序,就必须调用sort方法,传入比较器匿名内部类重写compare方法,我们现在可以使用lambda表达式来简化代码。
ArrayList- list=newArrayList<>(); list.add(newItem(13,"背心",7.80)); list.add(newItem(11,"半袖",37.80)); list.add(newItem(14,"风衣",139.80)); list.add(newItem(12,"秋裤",55.33)); /* list.sort(newComparator
- (){ @Override publicintcompare(Itemo1,Itemo2){ returno1.getId()-o2.getId(); } }); */ list.sort((o1,o2)->o1.getId()-o2.getId()); System.out.println(list);
Lambda表达式中的闭包问题
这个问题我们在匿名内部类中也会存在,如果我们把注释放开会报错,告诉我num值是final不能被改变。这里我们虽然没有标识num类型为final,但是在编译期间虚拟机会帮我们加上final修饰关键字。
以上就是一文带你入门JDK8新特性——Lambda表达式的详细内容,更多关于JDK8Lambda表达式的资料请关注毛票票其它相关文章!
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。