Lambda表达式,就相当于把一个匿名类简写简写再简写,然后呢就是咱看到的简洁的Lambda式子啦。
比如有一个简简单单的匿名类
HeroChecker c1 = new HeroChecker() {
public boolean test(Hero h) {
return (h.hp>100 && h.damage<50);
}
};
把它外面的衣服去掉,只剩下方法参数和方法体:
HeroChecker c2 = (Hero h) ->{
return h.hp>100 && h.damage<50;
};
然后去掉return和{}:
HeroChecker c3 = (Hero h) ->h.hp>100 && h.damage<50;
再把参数类型给去掉:
HeroChecker c4 = h ->h.hp>100 && h.damage<50;
这就是一个很简洁的lambda表达式了,把c4作为参数传入方法中,就可以ok的使用啦。
filter(heros,c4);
然后更简单的是可以不用声明一个c4, 可以直接把lambda表达式写入参数:
filter(heros, h -> h.hp > 100 && h.damage < 50);
就更简单了。
lambda就是一种匿名方法,把方法作为参数传递的编程思想,但是看着简简单单,在真正运行的时候,还是会被java变成匿名类来编译的。
方法引用
引用静态方法:
如果在类中写好了一个静态方法,那么在传入参数的时候可以这样写:
引用对象方法:
和上面格式类似,只不过需要事先创建对象。
引用容器方法:
引用构造器:
package HELLOLambda;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Supplier;
public class Lanbdagouzaoqi {
public static void main(String[] args) {
Supplier<List> s =new Supplier<List>() {
public List get() {
return new ArrayList();
}
};
List st1=getList(s);//匿名类写法,我称之为脱了裤子放屁
List st2=getList(()->new ArrayList());//lambda表达式,无参的
List st3=getList(ArrayList::new);//上一行换种写法
}
public static List getList(Supplier<List> s) {
return s.get();
}
}
聚合操作:
普通遍历:
for (Hero h : heros) {
if (h.hp > 100 && h.damage < 50)
System.out.println(h.name);
}
聚合操作的遍历(十分的高大上):
heros
.stream()
.filter(h -> h.hp > 100 && h.damage < 50)
.forEach(h -> System.out.println(h.name));
要了解聚合操作,首先得了解管道和stream
stream:流操作,就像一条生产线一样;
管道:一共分三步,也对应着上面例子那三行:
1、管道流
2、中间操作
3、结束操作
管道流:
把collection或者数组 转化成一个流。要注意的是collection可以直接.stream,而数组没有stream的方法,需要写
Arrays.stream(hs) //hs是一个数组
中间操作:
中间操作就是对流的筛选规则定义。
但是中间操作是一个懒操作,不会在执行到这条语句的时候就直接操作,而是等在进行“结束操作”的时候执行。
对元素进行筛选 和 转换为其他形式的流
对元素进行筛选:
- filter 匹配
- distinct 去除重复(根据equals判断)
- sorted 自然排序
- sorted(Comparator<T>) 指定排序 这里就比如
.sorted((h1,h2)->h1.hp>=h2.hp?
1
:-
1
) 引入了lambda直接定义排序规则
- limit 保留
- skip 忽略
转换为其他形式的流
mapToDouble 转换为double的流
map 转换为任意类型的流
结束操作:
就是对流的处理过程了,当执行完结束操作之后,流就被使用“光”了,所以结束操作是管道的最后一个操作。
常见结束操作如下:
- forEach() 遍历每个元素
- toArray() 转换为数组
- min(Comparator<T>) 取最小的元素
- max(Comparator<T>) 取最大的元素
- count() 总数
- findFirst() 第一个元素
作业:
首选准备10个Hero对象,hp和damage都是随机数。
分别用传统方式和聚合操作的方式,把hp第三高的英雄名称打印出来
package HELLOLambda;
import java.util.Random;
import java.util.ArrayList;
import java.util.List;
import charactor.Hero;
public class Aggregate_Excerse {
public static void main(String[] args) {
Random r = new Random();
List<Hero> heros = new ArrayList<>();
for(int i = 0;i < 10;i ++)
{
heros.add(new Hero("hero "+i,r.nextInt(1000),r.nextInt(1000)));
}
System.out.println("初始:");
heros.stream().forEach(h->System.out.println(h));
System.out.println("排序完第三大:");
Hero h=heros
.stream()
.sorted((h1,h2)->(int)(h2.hp-h1.hp))
.skip(2)
.findFirst()
.get();
System.out.println(h.name);
}
}