java8中lamba表达式的使用
(-1)前言
学习lamba表达式是十分重要的,你会发现java变的可爱多了。
(0)函数式接口
只有一个方法的接口称为函数式接口
JButtonjButton=newJButton("123"); jButton.addActionListener(newActionListener(){ @Override publicvoidactionPerformed(ActionEvente){}});
等同于
jButton.addActionListener(e->System.out.println("Helloworld")); jButton.addActionListener((e)->System.out.println("Helloworld")); jButton.addActionListener((ActionEvente)->System.out.println("Helloworld")); jButton.addActionListener((ActionEvente)->{System.out.println("Helloworld");return;});
a.规则
A->B
A部分是传入方法的参数
B部分是函数体
参数类型以及返回类型如果可以通过上下文推断出来可不写
当参数只有一个而且它的类型可以被推导得知时,该参数列表外面的括号可以被省略
当函数体只有一个语句且返回类型可被推导时{}可省略
b.例子
Runnablerunnable=()->System.out.println(sign); Runnablerunnable2=newRunnable(){ @Override publicvoidrun(){ //TODOAuto-generatedmethodstub} }; 通过匿名内部类我们知道run方法是不需要参数的 System.out.println(sign)相当于run方法的方法体 Comparator<Integer>lol=(x,y)->x-y; Comparator<Integer>lol=(x,y)->{System.out.println(x+y);returnx-y;}; newComparator<Integer>(){ @Override publicintcompare(Integero1,Integero2){ //TODOAuto-generatedmethodstub return0; } };
通过匿名内部类我们知道compare方法需要两个参数
这时编译通过Comparator<Integer>中Integer推导出参宿类型及返回类型
c.深入
lamba表达式可被看做函数,java.util.function定义了常用的函数式接口
http://docs.oracle.com/javase/8/docs/api/java/util/function/package-summary.html
BiFunction<T,U,R>
T代表第一个参数
U代表第二个参数
R代表返回值
这表时T,U,R都需要编译器根据上下文进行类型推导
Consumer<T> 代表e->System.out.println("Helloworld")
所以当一个方法需要的是lamba表达式时,参数展现形式是java.util.function中定义的样式
(2)方法引用
方法引用是对Lamba表达式的简化
类名::方法名(对象方法、类方法)
int[]oop={3,1,2,1}; staticvoidsayHello(Integername) { System.out.println(123); } Arrays.stream(oop).forEach(Test::sayHello); Arrays.stream(oop).forEach(s->Test.sayHello(s));
构造方法引用:Class::new
数组构造方法引用:TypeName[]::new
(3)强制类型转换
有时候编译器通过上下文推导出的返回类型与实际类型不符时需要进类型转换
Stream<Object>strings=shapelist.stream().<Object>map(s->s.getColor()); s.getColor())
s.getColor()返回的是String
(4)lamba表达式在java对象中的应用
你应该在任何java对象中尝试应用lamba表达式,通则是将这个对象转换成java.util.stream,流有串行并行之分哦!并行流关键字parallelStream
数组 Arrays.stream()
List、Set .stream()
String String.chars
...
java.util.stream提供了许多方法用来操作流中的数据,去试一试吧
http://docs.oracle.com/javase/8/docs/api/
java8英文API,没有找到中文的...
(2)对流整体的操作
比如我们可以求一个流的的总和
intsum=Arrays.stream(oop).sum(); intsum1=Arrays.stream(oop).reduce(0,(x,y)->x+y);
(3)集合之间的转换
我们可以将ArrayList<Shape>转换成ArrayList<String>、Set<String>、HashMap<String,String>,HashMap<String,Shape>甚至是更复杂的
a.map()
该方法是映射的意思(一开始我联想到了HashMap),还有mapToDouble等
b.collect()
collect()接受Collectors类型的参数,用来将流重新汇合,
Collectors是收集器,Collectors.toList(),Collectors.toMap()、Collectors.groupingBy等
c.例子
publicclassShape { privateStringcolor; publicShape(){ //TODOAuto-generatedconstructorstub } publicStringgetColor(){ returncolor; } publicvoidsetColor(Stringcolor){ this.color=color; } publicShape(Stringcolor) { this.color=color; } } ArrayList<String>colorList=newArrayList<String>(){ { add("Red"); add("Blue"); add("Yellow"); } }; List<Shape>shapeList=colorList.stream().map(Shape::new).collect(Collectors.toList()); List<String>colos=shpaeList.stream().map(s->s.getColor()).collect(Collectors.toList()); Set<String>colosSet=shpaeList.stream().map(s->s.getColor()).collect(Collectors.toSet()); Map<String,String>colorMap=colorList.stream().collect(Collectors.toMap(a->a,s->s)); Map<String,Shape>shapesMap=shpaeList.stream().collect(Collectors.toMap(s->s.getColor(),s->s));
Eclipse点不出getColor()方法,还以为用法不对...
Map<String,Set<Shape>>shapeMapSet=shpaeList.stream().collect(Collectors.groupingBy(s->s.getColor(),Collectors.toSet())); Map<String,Map<String,List<Shape>>>shapeMap3=shpaeList.stream().collect(Collectors.groupingBy(s->s.getColor(),Collectors.groupingBy(s->s.getColor(),Collectors.toList())));
(4)集合本身的操纵
想要改变现有集合而不产生新的集合可以使用
Iterable.forEach(Consumer),Collection.removeAll(Predicate),List.replaceAll(UnaryOperator),List.sort(Comparator)和Map.computeIfAbsent()等 shpaeList.sort(Comparator.comparing(Shape::getColor));
以上所述是小编给大家介绍的java8中lamba表达式的使用,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对毛票票网站的支持!