JDK 1.8-Stream中常用的API

本文详细介绍了JDK 1.8中Stream API的特性、缺点及运行机制,包括如何创建Stream、常用的中间操作如filter、distinct、sorted等,以及终止操作、查找和匹配、规约reduce、Collectors收集器的使用。此外,还讨论了Stream的并行流转换及其优势。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

JDK 1.8-Stream中常用的API

1. Stream

Stream是一组用来处理数组,集合的API

1.1特性

  1. 不是数据结构,没有内部存储
  2. 不支持索引访问
  3. 延时计算
  4. 支持并行
  5. 很容易生成数据或集合
  6. 支持过滤,查找,转换,汇总,聚合等操作

1.2缺点

  1. 若不用并行计算,很多时候计算速度没有比传统的 for 循环快。
  2. 不容易使用debug模式调试。
  3. 在 lambda 语句中直接强制类型转换不方便。
  4. 不可以在foreach中修改foreach外面的值。

1.3 运行机制

Stream分为源source,中间操作,终止操作。一个流只会有一个终止操作,Stream只有遇到终止操作,它的源才会开始执行遍历操作。一个流只能使用一次。

1.3 Stream的创建

1.通过数组
String[] str={“a”,”b”,”c”}
Stream str1=Stream.of(str);
2.通过集合
List list=Arrays.asList(“a”,”b”,”c”);
Stream stream=list.stream();
3.通过iterate
Stream iterate=Stream.iterate(1,X->x+1);
Iterate.forEach(x->System.out.println(x));

2. Stream常用的API

2.1中间操作

2.1.1 filter过滤

Filter会根据条件截取流中符合条件的数据。
List integerList=Arrays.asList(1,2,3,4,5,6);
List collect=integerList.stream().filter(i->i%2==0).collect(Collectors.toList());

2.1.2 distinct去重

返回一个元素各异的流(根据流所生成元素的hashCode和Equals方法实现)
List numbers=Arrays.asList(1,1,2,2,3,4);
List collect=numbers.stream().distinct().collect(Collectors.toList());

2.1.3 sorted 排序

对流中的数据进行排序,可以用自然序或Comparator接口定义排序的规则,Comparator可以用lanbada表达式来初始化
List integers=Arrays.asList(1,9,8,3,4);
//排序默认为顺序
List sorted=integers.stream().sorted().collect(Collectors.toList());
//逆序
List reverseSorted
=integers.stream().sorted(Comparator.reverseOrder()).collect(Collectors.toList());
//使用lambada表达式排序
List userList
=userList.stream().sorted(Comparator.Comparing(User::getAge)).collect(Collectors.toList());
//集合简写方式
userList.sort((o1,o2)->{return o1.getAge()-o2.getAge();
});

//java 7的排序,顺序
userList.sort(new Comparator(){
@Override
Public int compare(User o1,User o2){
return o1.getAge().compareTo(o2.getAge());
}
})

2.1.4 Limit 截取

该方法返回一个不超过给定长度的流
List collect=integers.stream().limit(5).collect(Collectors.toList());

2.1.5 skip舍弃

该方法返回一个舍弃前面n个元素的流
List collect=integers.stream().skip(5).collect(Collectors.toList());

2.1.6 map,flatMap 归纳

该方法会接受一个函数作为参数,这个函数会被应用到每个元素上,并将其映射成一个新的元素。就是根据指定函数获取流中每个元素的数据,并重新组合成一个新的额元素。
List collect=UserList.Stream().map(User::getName).collect(Collectors.toList());

flatMap 把流中的层级结构扁平化,就是将最底层元素抽取出来放在一起。
Stream<List> s=Stream.of(
Arrays.asList(1),Arrays.asList(2),Arrays.asList(3)
);
Stream collect=s.flatMap(e->e.stream());

2.1.7 peek 插入执行动作

在流的每个元素恢复运行之前,插入执行一个动作。
List numbers =Arrays.asList(2,3,4,5);
List result
=numbers.stream().peek(x->System.out.println(x)).map(x->x+17).peek(x->System.out.println(x)).colllect(Collectors.toList());

2.1.8 collect 收集

collect是将最终stream中的数据收集起来,最终生成一个list、set或map。
List userList=User.getUserList();
//list
List collect=userList.stream().limit(10).collect(Collectors.toList());
//set
List collect1=userList.stream().limit(10).collect(Collectors.toSet());
//map
List<Long,String> collect2
=userList.stream().collect(Collectors.toMap(User::getId,User::getName));

2.2终止操作

  1. 循环 forEach
  2. 计算 min,max,count,average
  3. 匹配 anyMatch,allMatch,noneMatch,findFirst,findAny
  4. 汇聚 reduce
  5. 收集器 collect

2.3查找和匹配

2.3.1 anyMacth

流中是否有一个元素匹配到,返回boolean值。
boolean b=userList.stream().anyMatch(User::isMan);

2.3.2 allMatch

流中的元素是否全部匹配,返回boolean值
Boolean b=userList.stream().allMatch(e-> e.getAge<18);

2.3.3 noneMatch

流中没有任何元素匹配,返回boolean值
Boolean b=userList.stream().noneMatch(e-> e.getAge>60);

2.3.4 findAny

返回当前流中的任意元素
Optional any=userList.stream().findAny();

2.3.5 findFirst

找到想要的第一个元素
Optional user=userList.stream().filter(User::isMan).findFirst();

2.4 规约reduce

此类查询需要将流中所有元素反复结合起来,得到一个值,比如Integer值

2.4.1 元素求和

List integers=Arrays.asList(1,2,3,6,8);
//求list中的和,以0为基数
Integer reduce=integers.stream().reduce(0,(a,b)->a+b);
//Integer的静态方法
Int sum=integers.stream().reduce(Integer::sum);

2.4.2 最大值和最小值

//最小值
Optional min=integers.stream().reduce(Integer::min);
//最大值
Optional max=integers.stream().reduce(Integer::max);

2.5 Collectors收集器

2.5.1 查找流中的最大值,最小值 minBy,maxBy

//创建一个Comparator比较
Comparator userComparator=Comparator.compringInt(User::getAge);
//maxBy选出最大值
Optional collect=userList.stream().collect(Collectors.maxBy(userComparator));
//minBy选出最小值
Optional collect=userList.stream().collect(Collectors.minBy(userComparator));

2.5.2 summingInt 汇总

把对象映射成求和所需的int函数,返回一个收集器
int collect=userList.stream().collect(Collectors.summingInt(User::getAge));

2.5.3 averagingInt 平均数

Double collect=userList.stream().collect(Collectros.averagingInt(User::getAge))

2.5.4 joining 连接字符串

String collect=userList.stream().map(User::getName).collect(Collectors.joining());
//字符串连接,加分界符,
String collect=userList.stream().map(User::getName).collect(Collectors.joining(“,”));

2.5.5 counting 得到流中的总数

long l=userList.stream().collect(Collectors.counting());

2.6 groupingBy 分组

Map<Integer,List> map
=userList.stream().collect(Collectors.groupingBy(User::getType));
//按年龄分青年,中年,老年
Map<String,List> map=userList.stream().collect(Collectors.groupingBy(user->{
If(user.getAge()<18){
return “青年”;
}else if(user.getAge()<50){
return “中年”;
}else{
return “老年”;
}
}));

2.6.2 多级分组,先通过类型,在通过年龄分组

Map<Integer,Map<String,List>> collect
=userList.stream().collect(Collectors.groupingBy(User::getType,Collectors.groupingBy(e->{
if(e.getAge()<18){
return “青年”;
}else if(e.getAge()<50){
return “中年”;
}else{
return “老年”;
}
})));

2.6.3 按子组收集数据

例如,每个类型的人有多少个
Map<Integer,Long> collect=userList.stream().collect(Collectors.groupingBy(User::getType,counting()));

2.7 一些流操作

2.7.1 流转换为其他数据结构

//转成Array
String[] array=stream.toArray(String[]::new);
//转成collection
List list=stream.collect(Collectors.toList());
//转成string
String str=stream.collect(Collectors.joining(“,”));

2.7.2 转换大写

List out=wordList.stream().map(String::toUpperCase).collect(Collectros.toList());

2.7.3 平方数

List numList=Arrays.asList(1,2,3,4);
List num=numList.stream().map(i->i*i).collect(Collectors.toList());

2.7.4 forEach 循环

forEach 不能修改自己包含的本地变量值,也不能用 break/return 之类的关键字提前结束循环。
打印姓名
userList.stream().forEach(e->System.out.println(e.getName()));

2.7.5 List->Map (k1,k2)->k1 当有相同的key存在时,取已存在的key

Map<long,User> map
=userList.stream().collect(Collectors.toMap(User::getId,e->e,(k1,k2)->k1));

2.7.6 Array->List

List list=Stream.of(arrays).collect(Collectors.toList());

2.7.7 List->Array

String[] array=list.stream().toArray(String[]::new)

2.7.8 removeIf移除,将满足条件的内容移除掉

3. 并行流

并行流就是一个把内容分成多个数据块,并用不同的线程分别处理每个数据块的流。这样可以自动把给定的工作负荷分配多核处理器的所有内核处理。

3.1将顺序流转为并行流

顺序流转换成并行流,可以让求和并行运算
Stream s=Stream.iterate(1L,i->i+1).limit(1000);
Long sum=s.parallel().reduce(0L,Long::sum);
Stream在内部分成了几块。因此可以对不同的块独立并行归纳操作,同一个归纳操作会将各个子流的归纳结果合并起来,得到整个原始流的归纳结果。
对并行流调用sequenial方法就可以变成顺序流。
并行内部流默认的线程池 ForkJoinPool,它默认的线程数量就是处理器的数量。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值