持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第2天,点击查看活动详情
引入:
需求:查找集合中符合条件的人员
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("Luke");
list.add("Josh");
list.add("Cedric");
list.add("Chester");
list.add("Lin");
}
要求:查找出以L开头的并且长度为3的人,并打印出来。
传统使用for循环的时候,我们是这样做的。
将数组先循环一边,找出以L开头的人,再将结果集循环一遍,找出长度为3的。
List<String> list1 = new ArrayList();
for (String s : list) {
if (s.startsWith("L")) {
list1.add(s);
}
}
List<String> list2 = new ArrayList<>();
for (String s : list1) {
if (s.length()==3) {
list2.add(s);
}
}
System.out.println(list2);
此时我们用Stream流实现的话:
list.stream()
.filter(name -> name.startsWith("L"))
.filter(name -> name.length() == 3)
.forEach(name -> System.out.println(name));
1 Stream流的特点
专注于对容器对象的聚合操作
提供串行/并行两种模式
提高编程效率、可读性
使用步骤:
- 获取流
- 中间操作
- 终结操作
2 Stream流常用API简介
2.1 中间操作
- map 转换流,将一种类型的流转换为另外一种流
- filter 过滤流,过滤流中的元素,返回一个符合条件的Stream
- distinct 返回去重的Stream
- sorted 返回一个排序的Stream
- peek 主要用来查看流中元素的数据状态
- limit 返回前n个元素数据组成的Stream
- skip 返回第n个元素后面数据组成的Stream
- parallel 并行
- sequential 串行
- unordered 不保证有序
- concat 合成
中间操作可以有0个或者多个,打开流,过滤/映射,返回新流,交给下一个操作使用。
2.2 终结操作
- forEach 循环操作Stream中数据
- forEachOrdered
- toArray 返回流中元素对应的数组对象
- reduce 聚合操作,用来做统计
- collect 聚合操作,封装目标数据
- min 获取最小值
- max 获取最大值
- count 统计流中的元素个数
- iterator 返回此流元素的迭代器
- findFirst 获取第一个元素
- findAny 获取任一元素
- anyMatch 匹配其中一个
- allMatch 匹配所有元素
- noneMatch 所有数据都不符合条件返回true 终结操作只能有一个,代表最后的操作
3 Stream流常用API:获取流
获取流的时候,只需要调用集合的stream方法即可将一个集合转换为流对象
List<String> list = new ArrayList<>();
Stream<String> stream1 = list.stream();
4 Stream流常用API:forEach&filter&map&count
4.1 foreach
forEach可以对Stream流中的数据进行遍历
//获取一个Stream流
Stream<String> stream = Stream.of("Luke", "Josh", "Cedric", "Chester", "Coat");
//使用Stream流中的方法forEach对Stream流中的数据进行遍历
stream.forEach(name -> System.out.println(name));
4.2 filter
创建一个Stream流,对Stream流中的元素进行过滤,只要以L开头的人
Stream.of("Luke", "Josh", "Cedric", "Chester", "Coat")
.filter(name -> name.startsWith("L"))
.forEach(name -> System.out.println(name));
4.3 map
获取一个String类型的Stream流,使用map方法,把字符串类型的整数,转换(映射)为Integer类型的整数
Stream.of("1", "2", "3", "4")
.map(s -> Integer.parseInt(s))
.forEach(i -> System.out.println(i));
4.4 count
获取一个Stream流,统计元素个数
long count = list.stream().count();
5 Stream流常用API:collect
Stream流的收集方法
R collect(Collector collector)
它是通过工具类Collectors提供了具体的收集方式
public static <T> Collector toList():把元素收集到List集合中
public static <T> Collector toSet():把元素收集到Set集合中
public static Collector toMap(Function keyMapper,Function valueMapper):把元素收集到Map集合中
5.1 List
首先我们创建List集合对象
List<String> list = new ArrayList<String>();
list.add("Luke");
list.add("Lin");
list.add("Beth");
list.add("Donna");
得到名字为3个字母的流,并收集到List集合中
List<String> names = list.stream()
.filter(s -> s.length() == 3)
.collect(Collectors.toList());
5.2 Set
创建一个Set集合对象
Set<Integer> set = new HashSet<Integer>();
set.add(10);
set.add(20);
set.add(30);
set.add(33);
set.add(35);
得出大于25的数,并收集到Set集合中
Set<Integer> set1 = set.stream()
.filter(age -> age > 25)
.collect(Collectors.toSet());
5.3 Map
定义一个字符串数组,每一个字符串数据由姓名数据和年龄数据组合而成
String[] strArray = {"林青霞,30", "张曼玉,35", "王祖贤,33", "柳岩,25"};
得到字符串中年龄数据大于28的流并将操作完毕的数据收集到Map集合中
Stream.of(strArray)
.filter(s -> Integer.parseInt(s.split(",")[1]) > 28)
.collect(Collectors.toMap(
s -> s.split(",")[0],
s -> Integer.parseInt(s.split(",")[1])
));
6 Stream流常用API:skip&concat
6.1 skip
获取一个Stream流,并跳过前三个元素
String[] arr = {"美羊羊","喜洋洋","懒洋洋","灰太狼","红太狼"};
Stream.of(arr)
.skip(3)
.forEach(name -> System.out.println(name));
6.2 concat
//创建一个Stream流
Stream<String> stream1 = Stream.of("张三丰", "张翠山", "赵敏", "周芷若", "张无忌");
//获取一个Stream流
String[] arr = {"美羊羊","喜洋洋","懒洋洋","灰太狼","红太狼"};
Stream<String> stream2 = Stream.of(arr);
//把以上两个流组合为一个流
Stream.concat(stream1, stream2).forEach(name -> System.out.println(name));