目录
文中有使用到Java8的Lambda表达式,若未学习,可点击下方链接学习Lambda表达式
链接: https://blog.csdn.net/qq_41175917/article/details/118785333.
Stream 的三个操作步骤
- 1、创建 Stream
- 2、中间操作
- 3、终止操作(终端操作)
创建Stream的几种方式
- 1、通过 Collection 系列集合提供的 stream() 或 parallelStream()
List<String> list = new ArrayList<>(); Stream<String> stream = list.stream();
- 2、通过 Arrays 中的静态方法 stream() 获取数组流
String[] strArr = new String[10]; Stream<String> stream = Arrays.stream(strArr);
- 3、通过 Stream 类中的静态方法 of()
Stream<String> stream = Stream.of("aa", "bb", "cc");
- 4、创建无限流,打印出来的结果为:从0开始,每一个元素比上一个大2,无限大下去
Stream<Integer> integerStream = Stream.iterate(0, (x) -> x + 2);
中间操作
filter:排除
将list中小于等于20的值排除掉,最后遍历打印
// 排除掉小于等于20的元素
List<Integer> list = new ArrayList<Integer>(){{
add(23);
add(86);
add(19);
}};
Stream<Integer> stream = list.stream()
.filter((x) -> x > 20);
stream.forEach(System.out::println);
输出:
23
86
limit:截断
获取并且打印数组的前两个数据
// 获取前两个元素
List<Integer> list = new ArrayList<Integer>(){{
add(23);
add(86);
add(19);
}};
list.stream()
.limit(2)
.forEach(System.out::println);
输出:
23
86
skip(n):跳过元素
跳过元素,返回一个冷掉了前n个元素的流。若流中元素不足n个,则返回一个空流。与 limit(n) 互补。
// 跳过前两个元素
new ArrayList<Integer>() {{
add(23);
add(86);
add(19);
}}.stream()
.skip(2)
.forEach(System.out::println);
输出:
19
distinct:去重
对 list 中的数据进行equals()对比去重。若 list 中存放的是对象,那么需要重写 hashCode() 和 equals() 方法,否则由于对象使用equals()对比得到的结果是false,会导致无法去重。
// 去掉里面的重复项
new ArrayList<Integer>() {{
add(23);
add(86);
add(19);
add(86);
add(86);
}}.stream()
.distinct()
.forEach(System.out::println);
输出:
23
86
19
map:映射
将元素转换成其他形式或提取信息。接受一个函数作为参数,该函数会应用到每个元素上,并将其映射成一个新到元素。
// 将每个元素的值增加 100
new ArrayList<Integer>() {{
add(23);
add(86);
add(19);
}}.stream()
.map((i) -> i + 100)
.forEach(System.out::println);
输出:
123
186
119
sorted:排序
// 自然排序
new ArrayList<Integer>() {{
add(23);
add(86);
add(19);
}}.stream()
.sorted()
.forEach(System.out::println);
System.out.println("--------");
// 定制排序,使用 lambda 表达式实现sorted方法参数中的Comparator中的接口,自定义排序方式
new ArrayList<Integer>() {{
add(23);
add(86);
add(19);
}}.stream()
.sorted((num1,num2) -> num2.compareTo(num1))
.forEach(System.out::println);
输出:
19
23
86
--------
86
23
19
终止操作
allMatch:检查是否匹配所有元素
根据.allMatch 方法中的Lambda表达式,判断每个元素是否都满足条件,全部满足时返回true,有一个不满足则返回false
// 判断list中每个数组元素下标为1的元素是否都等于3
boolean allMatch = new ArrayList<Integer[]>() {{
add(new Integer[]{2, 3, 4});
add(new Integer[]{1, 3, 6});
add(new Integer[]{8, 3, 3});
}}.stream().allMatch((e) -> e[1] == 3);
System.out.println(allMatch);
输出:
true
anyMatch:检查是否至少匹配一个元素
根据.anyMatch 方法中的Lambda表达式,判断是否至少有一个元素满足条件,至少一个满足时返回true,全都不满足则返回false
// 判断list中是否至少有一个数组元素下标为2的元素等于4
boolean anyMatch = new ArrayList<Integer[]>() {{
add(new Integer[]{2, 3, 4});
add(new Integer[]{1, 3, 6});
add(new Integer[]{8, 3, 3});
}}.stream().anyMatch((e) -> e[2] == 4);
System.out.println(anyMatch);
输出:
true
noneMatch:检查是否没有匹配所有元素
根据.noneMatch 方法中的Lambda表达式,判断是否所有元素都不满足条件,都不满足时方式true,只要至少有一个元素满足了,就返回false
// 判断list中是否所有数组元素下标为2的元素都不等于7
boolean noneMatch = new ArrayList<Integer[]>() {{
add(new Integer[]{2, 3, 4});
add(new Integer[]{1, 3, 6});
add(new Integer[]{8, 3, 3});
}}.stream().noneMatch((e) -> e[2] == 7);
System.out.println(noneMatch);
输出:
true
findFirst:返回第一个元素
获取流中第一个元素,我们可以在前面加排序什么的,得到排序后的第一个,然后使用get()方法取出元素进行后续操作。
// 获取第一个数组元素中下标为1的值
Optional<Integer[]> optional = new ArrayList<Integer[]>() {{
add(new Integer[]{2, 3, 4});
add(new Integer[]{1, 3, 6});
add(new Integer[]{8, 3, 3});
}}.stream().findFirst();
// 如果optional的值 为空,那么可以设置替代值,当然需不需要看你需求
optional.orElse(new Integer[]{0,0,0});
System.out.println(optional.get()[1]);
输出:
3
findAny:返回当前流中的任意元素
Optional<Integer[]> optional = new ArrayList<Integer[]>() {{
add(new Integer[]{2, 3, 4});
add(new Integer[]{1, 3, 6});
add(new Integer[]{8, 3, 3});
}}.stream().findAny();
// 如果optional的值 为空,那么可以设置替代值,当然需不需要看你需求
optional.orElse(new Integer[]{0,0,0});
System.out.println(optional.get()[2]);
输出:
4
count:返回流中元素总个数
long count = new ArrayList<Integer[]>() {{
add(new Integer[]{2, 3, 4});
add(new Integer[]{1, 3, 6});
add(new Integer[]{8, 3, 3});
}}.stream().count();
System.out.println(count);
max:返回流中最大值
根据.max 方法中的Lambda表达式,自定义计算方式排序,得到你认为最大的元素。
// 获取所有数组元素中,数组2下标最大的数组,并且打印该数组下标2的元素
Optional<Integer[]> max = new ArrayList<Integer[]>() {{
add(new Integer[]{2, 3, 4});
add(new Integer[]{1, 3, 6});
add(new Integer[]{8, 3, 3});
}}.stream().max((a1, a2) -> a1[2].compareTo(a2[2]));
System.out.println(max.get()[2]);
输出:
6
min:返回流中最大值
根据.max 方法中的Lambda表达式,自定义计算方式排序,得到你最小的元素。
// 获取所有数组元素中,数组2下标最大的数组,并且打印该数组下标2的元素
Optional<Integer[]> min = new ArrayList<Integer[]>() {{
add(new Integer[]{2, 3, 4});
add(new Integer[]{1, 3, 6});
add(new Integer[]{8, 3, 3});
}}.stream().min((a1, a2) -> a1[2].compareTo(a2[2]));
System.out.println(min.get()[2]);
输出:
3
reduce:归约
可以将流中元素反复结合起来,得到一个值
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
// 将100作为基数,将list中的所有元素往100上累加,每加上一个元素,就把加后的值当作x,后一个元素当作y,再往后加
Integer reduce = list.stream()
.reduce(100, (x, y) -> x + y);
System.out.println(reduce);
// 没有基数,直接累加,但是因为没有起始值,所以结果可能为空,所以使用Optional接收值
Optional<Integer> reduce1 = list.stream()
.reduce(Integer::sum);
System.out.println(reduce1.get());
输出:
155
55
collect:收集
将流转换为其他形式。接收一个Collector接口的实现,用户给Stream中元素做汇总的方法。
汇总
// 把list中每个数组元素的第3个元素取出来,放到一个新的list中
ArrayList<Integer[]> list = new ArrayList<Integer[]>() {{
add(new Integer[]{2, 3, 4});
add(new Integer[]{1, 3, 6});
add(new Integer[]{8, 3, 3});
}};
List<Integer> collect = list
.stream()
.map((a) -> a[2])
.collect(Collectors.toList());
collect
.stream()
.forEach(System.out::println);
输出:
4
6
3
若我们需要放到特殊的容器中,比如HashSet
.collect(Collectors.toCollection(HashSet::new));
计算
ArrayList<Integer[]> list = new ArrayList<Integer[]>() {{
add(new Integer[]{2, 3, 4});
add(new Integer[]{1, 3, 6});
add(new Integer[]{8, 3, 3});
}};
// 获取总数 结果 3
Long collect = list.stream().collect(Collectors.counting());
// 平均值(每个数组元素的第三个值,取出来算平均值) 结果 4.33333
Double collect1 = list.stream().collect(Collectors.averagingInt((a) -> a[2]));
// 求和(每个数组元素的第三个值,取出来求和) 结果 13.0
Double collect2 = list.stream().collect(Collectors.summingDouble((a) -> a[2]));
// 获取每个元素下标为2的最大值 结果 6
Optional<Integer> collect3 = list.stream().map((x)->x[2]).collect(Collectors.maxBy((a1, a2) -> a1.compareTo(a2)));
// 获取每个元素下标为2的最小值 结果 3
Optional<Integer> collect4 = list.stream().map((x)->x[2]).collect(Collectors.minBy(Integer::compareTo));
// 总函数
DoubleSummaryStatistics collect = list.stream().collect(Collectors.summarizingDouble((e) -> e[2]));
System.out.println("求和:" + collect.getSum());
System.out.println("平均值:" + collect.getAverage());
System.out.println("最大值:" + collect.getMax());
分组
// 按照每个数组的第二个元素进行分组
ArrayList<Integer[]> list = new ArrayList<Integer[]>() {{
add(new Integer[]{2, 3, 4});
add(new Integer[]{1, 3, 6});
add(new Integer[]{8, 4, 3});
}};
Map<Integer, List<Integer[]>> collect = list.stream().collect(Collectors.groupingBy((e) -> e[1]));
System.out.println(new Gson().toJson(collect));
输出:
{"3":[[2,3,4],[1,3,6]],"4":[[8,4,3]]}
多级分组
// 先按照每个数组多第二个元素进行分组,然后每个分组里,按照第一个元素进行分组
ArrayList<Integer[]> list = new ArrayList<Integer[]>() {{
add(new Integer[]{2, 3, 4});
add(new Integer[]{1, 3, 6});
add(new Integer[]{1, 3, 7});
add(new Integer[]{8, 4, 3});
}};
Map<Object, Map<Object, List<Integer[]>>> collect = list.stream()
.collect(Collectors.groupingBy((e) -> e[1]
,Collectors.groupingBy((q) -> q[0])
));
System.out.println(new Gson().toJson(collect));
输出:
{"3":{"1":[[1,3,6],[1,3,7]],"2":[[2,3,4]]},"4":{"8":[[8,4,3]]}}
分区
// 每个数组的第一个元素为1的分到true这一区,不为1的分false区
ArrayList<Integer[]> list = new ArrayList<Integer[]>() {{
add(new Integer[]{2, 3, 4});
add(new Integer[]{1, 3, 6});
add(new Integer[]{1, 3, 7});
add(new Integer[]{8, 4, 3});
}};
Map<Boolean, List<Integer[]>> collect = list.stream().collect(Collectors.partitioningBy((e) -> e[0] == 1));
System.out.println(new Gson().toJson(collect));
输出:
{"false":[[2,3,4],[8,4,3]],"true":[[1,3,6],[1,3,7]]}
字符串连接
// 讲每个数组的第3个元素取出来拼接在一起
ArrayList<String[]> list = new ArrayList<String[]>() {{
add(new String[]{"2", "3", "4"});
add(new String[]{"1", "5", "6"});
}};
String collect = list.stream()
.map((e) -> e[2])
.collect(Collectors.joining());
System.out.println(collect);
collect = list.stream()
.map((e) -> e[2])
.collect(Collectors.joining(","));
System.out.println(collect);
collect = list.stream()
.map((e) -> e[2])
.collect(Collectors.joining(",","前缀-- "," --结尾"));
System.out.println(collect);
输出:
46
4,6
前缀-- 4,6 --结尾