一、筛选满足条件的数据
1、匿名类方式,见如下代码
不知道什么原因没有显示筛选出来的结果
一、接口
package practice;
import charactor.Hero;
public interface HeroChecker {
public boolean test(Hero h);
}
二、package practice;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import charactor.Hero;
public class TestNm {
public static void main(String[] args) {
// TODO Auto-generated method stub
Random r=new Random();
List<Hero> heros=new ArrayList<>();
for(int a=0;a<10;a++){
heros.add(new Hero("hero"+a,r.nextInt(100),r.nextInt(100)));
}
System.out.println("初始化:");
System.out.println(heros);
System.out.println("使用匿名类的方式筛选出hp>100&&damage<50的英雄");
HeroChecker checker=new HeroChecker(){
public boolean test(Hero h){
return(h.hp>100 && h.damage<50);
}
};
filter(heros, checker);
}
private static void filter(List<Hero>heros,HeroChecker checker){
for(Hero hero:heros){
if(checker.test(hero))
System.out.println(hero);
}
}
}
2、Lambda方式,见代码
也没有显示出来结果,继续探索吧
package practice;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import charactor.Hero;
public class TestLambda {
public static void main(String[] args) {
// TODO Auto-generated method stub
Random r=new Random();
List<Hero>heros = new ArrayList<>();
for(int a=1;a<=10;a++){
heros.add(new Hero("hero"+a,r.nextInt(100),r.nextInt(100)));
}
System.out.println("初始化:");
System.out.println(heros);
System.out.println("使用lanbda方式筛选中");
filter(heros,h->h.hp>100&&h.damage<50);
}
private static void filter(List<Hero>heros,HeroChecker checker){
for(Hero hero:heros){
if(checker.test(hero))
System.out.println(hero);
}
}
}
3、从匿名类如何演变成lambda表达式
匿名类的正常写法:
HeroChecker tt=new HeroChecker(){
public boolean test(Hero h){
return(h.hp>100&&h.damage<50);
}
}
演变;lambda表达式中
1:把外面壳子去掉,只保留方法参数和方法体,参数和方法体之间加上符号->
HeroChecker tt=(Hero h)->{return(h.hp>100&&h.damage<50);};
2:把return和{}去掉
HeroChecker tt=(Hero h)->h.tp>100&&h.damage<50;
3、把参数类型和()去掉
注意只有一个参数的时候才能去掉()
HeroChecker tt=h->h.hp>100&&h.damage<50;
4、把tt作为参数传递进去
filter(heros,tt)
继续传递
filter(heros,h->hp>100&&h.damage<50);
4、lambda其实就是匿名方法,这是一种把方法作为参数进行传递的编程思想
虽然代码这样写:filter(heros,h->h.hp>100&&h.damage<50);
但是java背后还是会把这些还原成匿名方式
引入lambda表达式会使得代码更加紧凑,而不是各种接口和匿名类满天飞
lambda比较适合简短的业务代码中,并不适合在复杂的系统中,会加大维护成本
二、方法引用
1、引用静态方法
首先在TestLambda中添加一个静态方法
public static boolean testHero(Hero h){
return h.hp>100&&h.damage<50;
}
在lambda中调用这个静态方法(第一种写法):
filter(heros,TestLambda.testHero(Hero h));
第二种写法:
filter(heros.TestLambda::testHero);
2、引用对象方法(与静态方法类似,只是在传递的时候需要一个对象存在)
TestLambda testLambda=new TestLambda();
fiter(heros,testLambda::testHero);
3、引用容器中的对象的方法
首先为Hero添加一个方法
public boolean tt(Hero h){
return this.hp>100&&this.damage<50;
}
在Lambda中调用tt
filter(heros,h->h.tt());
可以进一步改写为:
filter(heros,Hero::tt);
4、引用构造器(没有搞懂,碰到再问 吧)
三、聚合操作
1、比较传统方式遍历与聚合操作方式遍历
//传统方式
for(Hero h:heros){
if(h.hp>100&&h.damage<50)
System.out.println(h.name);
}
//聚合方式
heros
.streanm()
.filter(h->h.hp>100&&h<50)
.forEach(h->System.out.println(h.name));
2、建立Stream和管道的概念
Stream和Collection结构化的数据不一样,Stream是一系列的元素,就像生产线一样列出来
注意这个Stream和InputStream是不一样的概念
管道指的是一系列的聚合操作
管道分三个部分:管道源、中间操作、结束操作
管道源:把Collection切换成管道很简单,调用stream()就行了
heros.stream()
但是数组却没有stream()方法就需要使用
Arrays.stream(hs)或者Stream.of(hs)
//管道源是集合
heros
.stream()
.forEach(h->Syatem.out.println(h.name));
//管道源是数组
Hero hs[]=heros.toArray(new Hero[heros.size()]);
Array.stream(hs)
.forEach(h->System.out.println(h.name);
中间操作:
每个中间操作又会返回一个Stream,比如.filter()又返回一个Stream,中间操作是懒操作并不会 真正进行遍历,中间操作比较多,主要分两类:
对元素进行筛选---
filter | distinct | sorted | sorted(Comparator<T> | limit | skip |
匹配 | 去除重复 | 自然排序 | 指定排序 | 保留 | 忽略 |
转换为其他形式的流
mapToDouble | 转换为double流 |
map | 转换为任意流 |
结束操作
当进行结束操作后,流就被使用光了,无法再被操作。所以这必定是流的最后一个操作。结束 操作不会返回Stream,但是会返回int,float,String,Collection或者像forEach(),什么都不返回。
结束操作才真正进行遍历,前面的中间操作也在这个时候真正进行,常见结束操作如下:
forEach() | toArray() | min(Comparator<T>) | max(Comparator<T>) | count() | findFirst() |
遍历每个元素 | 转换为数组 | 取最小的元素 | 取最大的元素 | 总数 | 第一个元素 |
package practice;
import java.util.ArrayList;
import java.util.List;
import charactor.Hero;
import java.util.Random;
import java.util.Arrays;
public class TestLambda {
public static void main(String[] args) {
// TODO Auto-generated method stub
List<Hero> heros=new ArrayList<>();
Random r=new Random();
for(int a=1;a<11;a++){
heros.add(new Hero("hero"+a,r.nextInt(100),r.nextInt(100)));
}
Object[] hs=heros
.stream()
.toArray();
System.out.println("返回一个数组:"+Arrays.toString(hs));
Hero minDamage=
heros
.stream()
.min((h1,h2)->h1.damage-h2.damage)
.get();
System.out.println("伤害最低的英雄是:"+minDamage);
Hero maxHp=
heros
.stream()
.max((h3,h4)->h3.hp-h4.hp)
.get();
System.out.println("血量最多的是:"+maxHp);
long count=
heros
.stream()
.count();
System.out.println("总数:"+count);
Hero firstHero=
heros
.stream()
.findFirst()
.get();
System.out.println("第一个英雄是:"+firstHero);
}
}