StreamAPI
最近开发用上了
Java8的StreamAPI,(咋现在才用?嗯哼,项目需要)自己也不怎么会,来总结一波吧!别认为好抽象!!!干他就完事
一.StreamAPI介绍
就是用来处理集合的数据 其实到后面会发现和SQL的语句是差不多的~哈哈?你不信?往下面看
Stream:英文翻译叫做流
举个粟子:
Stream相当于一条河流,数据相当于里面的水,这条河流里面的水你要饮用还是其他操作叫做Stream的执行数据操作,从而达到你要的目的(比如达成饮用水的目的),在计算机中就是处理达成你要的结果
注意!
Stream不会自己存储元素- 不会改变源对象,只是返回含有结果的一个新
Stream - 延迟执行,在要结果的时候才执行(有点像懒汉模式)

二.流操作的过程
主要就是从生到死周期
- 创建Stream:就是从一个数组或者集合拿取数据(相当于找到水源地)
//主要两种创建方式:
1.Steam()
2.parallelStream() //这个主要返回并行流
//eg:
List<String> list=new ArrayList<>();
Stream<String> s1=list.stream();//
===========================================
//值创建流 Stream.of() 静态方法显示创建
Stream<String> s=Stream.of("a","s","ddddd");
s.forEach(System.out::println);
==============================================
//创建无限流
Stream.iterate() 和 Stream.generate()两个方法
//举例 迭代
Steam<Integer> s=Stream.iterate(0,(x)->x>>1);
s.limit(10).forEach(System.out::println);
//举例 生成
Stream.generate(()->Math.random().limit(6)
forEach(System.out::println));
- **中间逻辑操作:**就相当于SQL语句中执行条件,处理达到你要的结果和业务数据(比如你要取水去做饮用水啊中间是不是要净化啥的操作)
看下面的主题,太多了,但也是重点
- **结束:**就是终止条件,写结果返回语句,不能无休止啊
三.中间操作
在
终止操作时才会一次性全部处理,就是要到开学了,小学生才会用功写完全部作业~哈哈
filter,limit,skip,distinct
1.筛选切片
Filter:接受
Lambda,进行过滤操作,排除一些不需要的元素
// (1)filter——接收 Lambda , 从流中排除某些元素。
@Test
public void testFilter() {
//这里加入了终止操作 ,不然中间操作一系列不会执行
//中间操作只有在碰到终止操作才会执行
emps.stream()
.filter((e)->e.getAge()>18) //过滤只要年龄大于18 的
.forEach(System.out::println);//终止操作
}
limit(n):截取指定n个以内数量的元素
// (2)limit——截断流,使其元素不超过给定数量。
@Test
public void testLimit() {
emps.stream()
.filter((e)->e.getAge()>8)
.limit(6)//跟数据库中的limit有差不多
.forEach(System.out::println);//终止操作
}
skip(n):跳过元素,就是前n个元素不要,从第
n+1个数开始,没有,就返回空
// (3)skip(n) —— 跳过元素,返回一个扔掉了前 n 个元素的流。若流中元素不足 n 个,则返回一个空流。与 limit(n) 互补
@Test
public void testSkip() {
emps.stream()
.filter((e)->e.getAge()>8)
.skip(2)//这里可以查找filter过滤后的数据,前两个不要,要后面的,与limit相反
.forEach(System.out::println);//终止操作
}
distinct:就是去重,返回不重复的元素
原理:利用
hashCode()和equals()去除重复的元素,
// (4)distinct——筛选,通过流所生成元素的 hashCode() 和 equals() 去除重复元素
@Test
public void testDistinct() {
emps.stream()
.distinct()//去除重复的元素,因为通过流所生成元素的 hashCode() 和 equals() 去除重复元素,所以对象要重写hashCode跟equals方法
.forEach(System.out::println);//终止操作
}
2.Map映射
- map()
- mapToDouble()
- mapToInt()
- mapToLong()
- flatMap()
map():就是接受一个函数作为参数,该参数会被应用到每个元素上,并且映射成一个新的元素
flatMap():接受一个函数作为参数,并且将流中每个值转换成另一个流,然后把所有的流连成一个流
直接复制了哈,这个代码感觉还是不错的,一起看看吧~哈哈
// map-接收Lambda,将元素转换成其他形式或提取信息。接收一个函数作为参数,该函数会被应用到每个元素上,并将其映射成一个新的元素。
@Test
public void testMapAndflatMap() {
List<String> list=Arrays.asList("aaa","bbb","ccc","ddd");
list.stream()
.map((str)->str.toUpperCase())//里面是Function
.forEach(System.out::println);
System.out.println("----------------------------------");
//这里是只打印名字,map映射,根据Employee::getName返回一个name,映射成新的及结果name
emps.stream()
.map(Employee::getName)
.forEach(System.out::println);
System.out.println("======================================");
//流中流
Stream<Stream<Character>> stream = list.stream()
.map(StreamAPI::filterCharacter);
//{{a,a,a},{b,b,b}}
//map是一个个流(这个流中有元素)加入流中
stream.forEach(sm->{
sm.forEach(System.out::println);
});
System.out.println("=============引进flatMap=============");
// 只有一个流
Stream<Character> flatMap = list.stream()
.flatMap(StreamAPI::filterCharacter);
//flatMap是将一个个流中的元素加入流中
//{a,a,a,b,b,b}
flatMap.forEach(System.out::println);
}
/**
* 测试map跟flatMap的区别
* 有点跟集合中的add跟addAll方法类似 这个就好理解多了
* add是将无论是元素还是集合,整体加到其中一个集合中去[1,2,3.[2,3]]
* addAll是将无论是元素还是集合,都是将元素加到另一个集合中去。[1,2,3,2,3]
* @param str
* @return
*/
public static Stream<Character> filterCharacter(String str){
List<Character> list=new ArrayList<>();
for (Character character : str.toCharArray()) {
list.add(character);
}
return list.stream();
}
3.排序
自然排序:
sorted()定制排序:
sorted(Comparator c): 就是里面写你想添加判断条件
货不多说,看测试代码
@Test
public void testSorted() {
List<String> list=Arrays.asList("ccc","aaa","bbb","ddd","eee");
list.stream()
.sorted()
.forEach(System.out::println);
System.out.println("=======定制排序=========");
//=====仔细瞅瞅这边
emps.stream()
.sorted((x, y) -> {
if(x.getAge() == y.getAge()){
return x.getName().compareTo(y.getName());
}else{
return Integer.compare(x.getAge(), y.getAge());
}
}).forEach(System.out::println);
}
四.结束
1.查找与匹配
allMatch(): 检查是否匹配所有元素
anyMatch(): 检查是否至少匹配一个元素
noneMatch(): 是否没有匹配的所有元素
findFirst(): 返回第一个元素
findAny(): 返回当前流中的任意元素
count(): 返回流中的元素总数
max(),min(): 返回流中的最大最小值
forEach(): 就是迭代循环,贼常用的
**测试代码:**复制过来的,写的不好,可以留言哈!!!
//3. 终止操作
/*查找与匹配
allMatch——检查是否匹配所有元素
anyMatch——检查是否至少匹配一个元素
noneMatch——检查是否没有匹配的元素
findFirst——返回第一个元素
findAny——返回当前流中的任意元素
count——返回流中元素的总个数
max——返回流中最大值
min——返回流中最小值
*/
@Test
public void test() {
// emps.stream():获取串行流
// emps.parallelStream():获取并行流
System.out.println("==========allMatch==============");
boolean allMatch = emps.stream()
.allMatch((e)->e.getStatus().equals(Status.BUSY));
System.out.println(allMatch);
System.out.println("==========anyMatch==============");
boolean anyMatch = emps.stream()
.anyMatch((e)->e.getAge()>10);
System.out.println(anyMatch);
System.out.println("==========noneMatch==============");
boolean noneMatch = emps.stream()
.noneMatch((e)->e.getStatus().equals(Status.BUSY));
System.out.println(noneMatch);
System.out.println("==========findFirst==============");
Optional<Employee2> findFirst = emps.stream()
.sorted((e1, e2) -> Double.compare(e1.getSalary(), e2.getSalary()))//按照工资排序并输出第一个
.findFirst();
System.out.println(findFirst);
System.out.println("==========findAny==============");
Optional<Employee2> findAny = emps.stream()
.filter((e)->e.getStatus().equals(Status.BUSY))
.findAny();
System.out.println(findAny);
System.out.println("==========count==============");
long count = emps.stream()
.count();
System.out.println(count);
System.out.println("==========max==============");
Optional<Double> max = emps.stream()
.map(Employee2::getSalary)
.max(Double::compare);
System.out.println(max);
System.out.println("==========min==============");
Optional<Employee2> min = emps.stream()
.min((e1,e2)->Double.compare(e1.getSalary(), e2.getSalary()));
System.out.println(min);
}
2.归纳
reduce(T iden,BinaryOperator b):流中元素反复结合得到一个值,返回T
reduce(BinaryOperator b):流中元素反复结合得到一个值,返回Optional<T>
map-reduce模式感兴趣可以骚操作一波
@Test
public void testReduce() {
List<Integer> list= Arrays.asList(1,2,3,4,5,6,7,8,9,10);
Integer sum = list.stream()
.reduce(0,(x,y)->x+y);
System.out.println(sum);
Optional<Double> reduce = emps.stream()
.map(Employee2::getSalary)
.reduce(Double::sum);
System.out.println(reduce.get());
}
3.收集
collect():你想收集成啥样的集合返回
Collectors其中主要的方法:
方法名 作用 返回类型 toSet把流中元素收集到set Set toList将流中的元素收集到 ListList toCollection:将流中的元素收集到自己创建的集合中 Collection counting计算流中的元素个数 long summingInt对元素中的整数类型求和 Integer averagingInt求平均值 Double summarizingInt收集流中Integer属性的统计值 IntSummaryStatistics
方法 作用 返回类型 joining连接流中的每个字符串 String maxBy,minBy根据比较器选择最大最小值 Optional reducing归约 归约产生的类型 collectingAndThen包裹另一个收集器并对其结果转换函数 转换函数返回的类型 groupingBy根据某些属性值对流分组,属性为 k,结果为vMap<K,List> partitioningBy根据true或false进行分区 Map<Boolean,List>
测试代码:
//===============
List<String> collect = emps.stream()
.map(Employee2::getName)
.collect(Collectors.toList());
collect.forEach(System.out::println);
//=====================================================
Set<String> collect2 = emps.stream()
.map(Employee2::getName)
.collect(Collectors.toSet());
collect2.forEach(System.out::println);
//=======================================================
HashSet<String> collect3 = emps.stream()
.map(Employee2::getName)
.collect(Collectors.toCollection(HashSet::new));
collect3.forEach(System.out::println);
//======================================================
Optional<Double> collect = emps.stream()
.map(Employee2::getSalary)
.collect(Collectors.maxBy(Double::compare));
System.out.println(collect.get());
Optional<Employee2> collect2 = emps.stream()
.collect(Collectors.maxBy((e1, e2) -> Double.compare(e1.getSalary(), e2.getSalary())));
System.out.println(collect2.get());
//=======================================================
Optional<Double> collect4 = emps.stream()
.map(Employee2::getSalary)
.collect(Collectors.minBy(Double::compare));
System.out.println(collect4);
Optional<Employee2> collect3 = emps.stream()
.collect(Collectors.minBy((e1,e2)->Double.compare(e1.getSalary(),e2.getSalary())));
System.out.println(collect3.get());
//====================================================
Double collect5 = emps.stream()
.collect(Collectors.summingDouble(Employee2::getSalary));
System.out.println(collect5);
//========================================================
Double collect6 = emps.stream()
.collect(Collectors.averagingDouble((e)->e.getSalary()));
Double collect7 = emps.stream()
.collect(Collectors.averagingDouble(Employee2::getSalary));
System.out.println("collect6:"+collect6);
System.out.println("collect7:"+collect7);
//=======================================================
//总数
Long collect8 = emps.stream()
.collect(Collectors.counting());
System.out.println(collect8);
//====================================================
DoubleSummaryStatistics collect9 = emps.stream()
.collect(Collectors.summarizingDouble(Employee2::getSalary));
long count = collect9.getCount();
double average = collect9.getAverage();
double max = collect9.getMax();
double min = collect9.getMin();
double sum = collect9.getSum();
System.out.println("count:"+count);
System.out.println("average:"+average);
System.out.println("max:"+max);
System.out.println("min:"+min);
System.out.println("sum:"+sum);
//=========================================================
//分组
@Test
public void testCollect3() {
Map<Status, List<Employee2>> collect = emps.stream()
.collect(Collectors.groupingBy((e)->e.getStatus()));
System.out.println(collect);
Map<Status, List<Employee2>> collect2 = emps.stream()
.collect(Collectors.groupingBy(Employee2::getStatus));
System.out.println(collect2);
}
//=====多级==================================================
//多级分组
@Test
public void testCollect4() {
Map<Status, Map<String, List<Employee2>>> collect = emps.stream()
.collect(Collectors.groupingBy(Employee2::getStatus, Collectors.groupingBy((e)->{
if(e.getAge() >= 60)
return "老年";
else if(e.getAge() >= 35)
return "中年";
else
return "成年";
})));
System.out.println(collect);
}
//===================================================
//多级分组
@Test
public void testCollect4() {
Map<Status, Map<String, List<Employee2>>> collect = emps.stream()
.collect(Collectors.groupingBy(Employee2::getStatus, Collectors.groupingBy((e)->{
if(e.getAge() >= 60)
return "老年";
else if(e.getAge() >= 35)
return "中年";
else
return "成年";
})));
System.out.println(collect);
}
//==========================================================
//多级分组
@Test
public void testCollect4() {
Map<Status, Map<String, List<Employee2>>> collect = emps.stream()
.collect(Collectors.groupingBy(Employee2::getStatus, Collectors.groupingBy((e)->{
if(e.getAge() >= 60)
return "老年";
else if(e.getAge() >= 35)
return "中年";
else
return "成年";
})));
System.out.println(collect);
}
//======================================================
//组接字符串
@Test
public void testCollect6() {
String collect = emps.stream()
.map((e)->e.getName())
.collect(Collectors.joining());
System.out.println(collect);
String collect3 = emps.stream()
.map(Employee2::getName)
.collect(Collectors.joining(","));
System.out.println(collect3);
String collect2 = emps.stream()
.map(Employee2::getName)
.collect(Collectors.joining(",", "prefix", "subfix"));
System.out.println(collect2);
}
@Test
public void testCollect7() {
Optional<Double> collect = emps.stream()
.map(Employee2::getSalary)
.collect(Collectors.reducing(Double::sum));
System.out.println(collect.get());
}
//==========================================================
总测试代码
/**
* collect——将流转换为其他形式。接收一个 Collector接口的实现,用于给Stream中元素做汇总的方法
*/
@Test
public void testCollect() {
List<String> collect = emps.stream()
.map(Employee2::getName)
.collect(Collectors.toList());
collect.forEach(System.out::println);
Set<String> collect2 = emps.stream()
.map(Employee2::getName)
.collect(Collectors.toSet());
collect2.forEach(System.out::println);
HashSet<String> collect3 = emps.stream()
.map(Employee2::getName)
.collect(Collectors.toCollection(HashSet::new));
collect3.forEach(System.out::println);
}
@Test
public void testCollect2() {
Optional<Double> collect = emps.stream()
.map(Employee2::getSalary)
.collect(Collectors.maxBy(Double::compare));
System.out.println(collect.get());
Optional<Employee2> collect2 = emps.stream()
.collect(Collectors.maxBy((e1, e2) -> Double.compare(e1.getSalary(), e2.getSalary())));
System.out.println(collect2.get());
Optional<Double> collect4 = emps.stream()
.map(Employee2::getSalary)
.collect(Collectors.minBy(Double::compare));
System.out.println(collect4);
Optional<Employee2> collect3 = emps.stream()
.collect(Collectors.minBy((e1,e2)->Double.compare(e1.getSalary(),e2.getSalary())));
System.out.println(collect3.get());
System.out.println("=========================================");
Double collect5 = emps.stream()
.collect(Collectors.summingDouble(Employee2::getSalary));
System.out.println(collect5);
Double collect6 = emps.stream()
.collect(Collectors.averagingDouble((e)->e.getSalary()));
Double collect7 = emps.stream()
.collect(Collectors.averagingDouble(Employee2::getSalary));
System.out.println("collect6:"+collect6);
System.out.println("collect7:"+collect7);
//总数
Long collect8 = emps.stream()
.collect(Collectors.counting());
System.out.println(collect8);
DoubleSummaryStatistics collect9 = emps.stream()
.collect(Collectors.summarizingDouble(Employee2::getSalary));
long count = collect9.getCount();
double average = collect9.getAverage();
double max = collect9.getMax();
double min = collect9.getMin();
double sum = collect9.getSum();
System.out.println("count:"+count);
System.out.println("average:"+average);
System.out.println("max:"+max);
System.out.println("min:"+min);
System.out.println("sum:"+sum);
}
//分组
@Test
public void testCollect3() {
Map<Status, List<Employee2>> collect = emps.stream()
.collect(Collectors.groupingBy((e)->e.getStatus()));
System.out.println(collect);
Map<Status, List<Employee2>> collect2 = emps.stream()
.collect(Collectors.groupingBy(Employee2::getStatus));
System.out.println(collect2);
}
//多级分组
@Test
public void testCollect4() {
Map<Status, Map<String, List<Employee2>>> collect = emps.stream()
.collect(Collectors.groupingBy(Employee2::getStatus, Collectors.groupingBy((e)->{
if(e.getAge() >= 60)
return "老年";
else if(e.getAge() >= 35)
return "中年";
else
return "成年";
})));
System.out.println(collect);
}
//分区
@Test
public void testCollect5() {
Map<Boolean, List<Employee2>> collect = emps.stream()
.collect(Collectors.partitioningBy((e)->e.getSalary()>5000));
System.out.println(collect);
}
//组接字符串
@Test
public void testCollect6() {
String collect = emps.stream()
.map((e)->e.getName())
.collect(Collectors.joining());
System.out.println(collect);
String collect3 = emps.stream()
.map(Employee2::getName)
.collect(Collectors.joining(","));
System.out.println(collect3);
String collect2 = emps.stream()
.map(Employee2::getName)
.collect(Collectors.joining(",", "prefix", "subfix"));
System.out.println(collect2);
}
@Test
public void testCollect7() {
Optional<Double> collect = emps.stream()
.map(Employee2::getSalary)
.collect(Collectors.reducing(Double::sum));
System.out.println(collect.get());
}




















