A.Hello Lambda
一.从匿名类演变成Lambda表达式
1.匿名类写法
HeroChecker c1 = new HeroChecker(){
public boolean test(Hero h){
return (h.hp>100 && h.damage<50)
}
};
2.把外面的壳子去掉只保留方法参数->方法体
HeroChecker c2 = (Hero h)->{
return h.hp>100 && h.damage<50;
};
3.把return 和{}去掉
HeroChecker c3 = (Hero h)->h.hp>100 && h.damage<50;
4.把参数类型和圆括号去掉(只有一个参数时才可以去掉圆括号)
HeroChecker c4 = h->h.hp>100 && h.damage<50;
5.把c4作为参数传递进去
filter(heros,c4);
6.直接把表达式传递进去
filter(heros,h->h.hp>100&&h.damage<50)
二.匿名方法
与匿名类概念比较,Lambda其实就是匿名方法
这是一种把方法作为参数传递的编程思想
虽然代码是这么写的
filter(heros,h->h.hp>100 && h.damage<50)
但是Java会在背后悄悄地把这些都还原成匿名类方式
引入Lambda表达式会使代码更加紧凑而不是各种接口和匿名类到处飞
弊端:
可读性差,一旦变得比较长就难以理解
不便于调试,很难在表达式中增加调试信息
版本支持,JDK8以后支持
B.方法引用
1.引用静态方法
首先为TestLambda添加一个静态方法
public static boolean testHero(Hero h){
return h.hp>100 && h.damage<50;
}
Lambda表达式中调用这个静态方法
filter(heros,h->TestLambda.testHero(h));
filter(heros,TestLambda::testHero);//写法二
2.引用对象方法
与引用静态方法很类似,只是传递方法的时候需要一个对象的存在
TestLambda testLambda = new TestLambda();
filter(heros, testLambda::testHero);
3.引用容器中的方法
首先为Hero添加一个方法
public boolean matched(){
return this.hp>100 && this.damage<50;
}
filter(heros,h->h.matched());
filter(heros,Herp::matched);//写法二
4.引用构造器
有的接口中的方法会返回一个对象,比如java.util.function.Supplier提供了一个get方法,返回一个对象
public interface Supplier<T>{
T get();
}
设计一个方法,参数是这个接口
public static List getList(Supplier<List> s){
return s.get();
}
为了调用这个方法有三种方式
1.匿名类
Supplier<List> s = new Supplier<List>(){
public List get(){
return new ArrayList();
}
}
List list1 = getList(s);
2.Lambda表达式
List list2 = getList(()->new ArrayList());
3.引用构造器
List list3 = getList(ArrayList::new);
C.聚合操作
1.Stream和管道的概念
heros
.stream()
.filter(h -> h.hp > 100 && h.damage < 50)
.forEach(h -> System.out.println(h.name));
Stream和Collection结构化的数据不一样,
Stream是一系列的元素,就像生产线上的罐头一样,一串串的出来
管道是一系列的聚和操作又分为3部分
管道源:
中间操作:每个中间操作又会返回一个Stream。
中间操作是懒操作,并不会进行真正的便利
结束操作:是流的最后一个操作,当这个操作被执行完后流就被用光了,无法再被操作。
不会返回Stream,但是会返回int,float,String,Collection或者什么都不返回。
结束操作才进行真正的遍历,在遍历的时候才会去进行中间操作的相关判断
2.管道源
把Collection切换成管道源很简单,调用stream()就行了
heros.stream()
但是数组却没有stream()方法,需要使用
Arrays.stream(hs)或者Stream.of(hs)
3.中间操作
主要分为两类,对元素进行筛选和转换成其他形式的流
对元素进行筛选:
filter 匹配
distinct 去除重复(根据equals判断)
sorted 自然排序
sorted(Comparator<T>) 指定排序
limit 保留
skip 忽略
转换为其他形式的流
mapToDouble 转换成double的流
map 转换成任意类型的流
4.结束操作
常见结束操作如下:
forEach() 遍历每个元素
toArray() 转换为数组
min(Comparator<T>) 取最小的元素
max(Comparator<T>) 取最大的元素
count() 总数
findFirst() 第一个元素
网友评论