ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

Java8新特性之Stream--collect方法

2022-06-17 17:34:15  阅读:164  来源: 互联网

标签:Stream Collectors stream Person -- collect println personList


collect方法
收集(collect)
collect,收集,可以说是内容最繁多、功能最丰富的部分了。从字面上去理解,就是把一个流收集起来,最终可以是收集成一个值也可以收集成一个新的集合。
collect主要依赖java.util.stream.Collectors类内置的静态方法。

归集(toList/toSet/toMap)
因为流不存储数据,那么在流中的数据完成处理后,需要将流中的数据重新归集到新的集合里。 toList、toSet和toMap比较常用,另外还有toCollection、toConcurrentMap等复杂一些的用法。

List<Integer> list = Arrays.asList(1, 6, 3, 4, 6, 7, 9, 6, 20);
List<Integer> listNew = list.stream().filter(x -> x % 2 == 0).collect(Collectors.toList());
System.out.println("产生的新集合是:" + listNew);

Set<Integer> set = list.stream().filter(x -> x % 2 == 0).collect(Collectors.toSet());
System.out.println("产生的不重复的新集合是:" + set);

List<Person> personList = new ArrayList<>();
personList.add(new Person("Tom", 8900, 22, "male", "New Yark"));
personList.add(new Person("Jack", 7000, 29, "male", "Washington"));
personList.add(new Person("Lily", 7800, 24, "female", "Washington"));
personList.add(new Person("Anni", 8200, 28, "female", "New Yark"));
personList.add(new Person("Owen", 9500, 26, "male", "New Yark"));
personList.add(new Person("Alisa", 7900, 27, "female", "New Yark"));

Map<?, Person> personMap =
personList.stream().filter(p -> p.getSalary() > 8000).collect(Collectors.toMap(Person::getName,
p -> p));
System.out.println("产生的新的map集合是:" + personMap);

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
统计(count/averaging)
Collectors提供了一系列用于数据统计的静态方法:

计数:count
平均值:averagingInt、averagingLong、averagingDouble
最值:maxBy、minBy
求和:summingInt、summingLong、summingDouble
统计以上所有:summarizingInt、summarizingLong、summarizingDouble
1
2
3
4
5
/**
* 案例:统计员工人数、平均工资、工资总额、最高工资。
*/
// 求总数
Long count = personList.stream().collect(Collectors.counting());
System.out.println("员工总数:" + count);
// 求平均工资
Double avgSalary = personList.stream().collect(Collectors.averagingDouble(Person::getSalary));
System.out.println("员工平均工资:" + avgSalary);
// 求工资之和
Integer sumSalary = personList.stream().collect(Collectors.summingInt(Person::getSalary));
System.out.println("员工工资总和:" + sumSalary);
// 一次性统计所有信息
DoubleSummaryStatistics collect = personList.stream().collect(Collectors.summarizingDouble(Person::getSalary));
System.out.println("员工工资所有统计:" + collect);

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
分组(partitioningBy/groupingBy)
分区:将stream按条件分为两个Map,比如员工按薪资是否高于8000分为两部分。
分组:将集合分为多个Map,比如员工按性别分组。有单级分组和多级分组。
1
2
/**
* 案例:将员工按薪资是否高于8000分为两部分;将员工按性别和地区分组
*/
// 将员工按薪资是否高于8000分组
Map<Boolean, List<Person>> part =
personList.stream().collect(Collectors.partitioningBy(x -> x.getSalary() > 8000));
// 将员工按性别分组
Map<String, List<Person>> group = personList.stream().collect(Collectors.groupingBy(Person::getSex));
// 将员工先按性别分组,再按地区分组
Map<String, Map<String, List<Person>>> group2 =
personList.stream().collect(Collectors.groupingBy(Person::getSex,
Collectors.groupingBy(Person::getArea)));
System.out.println("员工按薪资是否大于8000分组情况:" + part);
System.out.println("员工按性别分组情况:" + group);
System.out.println("员工按性别、地区:" + group2);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
接合(joining)
joining可以将stream中的元素用特定的连接符(没有的话,则直接连接)连接成一个字符串。

String names = personList.stream().map(p -> p.getName()).collect(Collectors.joining(","));
System.out.println("所有员工的姓名:" + names);
List<String> strs = Arrays.asList("A", "B", "C");
String str = strs.stream().collect(Collectors.joining("-"));
System.out.println("拼接后的字符串:" + str);
1
2
3
4
5
归约(reducing)
Collectors类提供的reducing方法,相比于stream本身的reduce方法,增加了对自定义归约的支持。

// 每个员工减去起征点后的薪资之和
Integer sumsal = personList.stream().collect(Collectors.reducing(0, Person::getSalary, (x, y) -> x + y - 5000));
System.out.println("员工扣税薪资总和:" + sumsal);
// stream的reduce
Integer sum = personList.stream().map(Person::getSalary).reduce(0, (x, y) -> x + y - 5000);
System.out.println("----员工扣税薪资总和:" + sum);
1
2
3
4
5
6
排序(sorted)
sorted,中间操作。有两种排序:

sorted():自然排序,流中元素需实现Comparable接口
sorted(Comparator com):Comparator排序器自定义排序
1
2
/**
* 案例:将员工按工资由高到低(工资一样则按年龄由大到小)排序
*/
// 按工资升序排序(自然排序)
List<String> nameList =
personList.stream().sorted(Comparator.comparing(Person::getSalary)).map(Person::getName).collect(Collectors.toList());
System.out.println("按工资升序排序(自然排序):" + nameList);
// 按工资降序排序
List<String> nameList1 =
personList.stream().sorted(Comparator.comparing(Person::getSalary).reversed()).map(Person::getName).collect(Collectors.toList());
System.out.println("按工资降序排序:" + nameList1);

// 先按工资再按年龄升序排序
List<String> nameList2 =
personList.stream().sorted(Comparator.comparing(Person::getSalary).thenComparing(Person::getSalary
)).map(Person::getName).collect(Collectors.toList());
System.out.println("先按工资再按年龄升序排序:" + nameList2);

// 先按工资再按年龄自定义排序(降序)
List<String> nameList3 = personList.stream().sorted((p1, p2) -> {
if (p1.getSalary() == p2.getSalary()) {
return p2.getAge() - p1.getAge();
} else {
return p2.getSalary() - p1.getSalary();
}
}).map(Person::getName).collect(Collectors.toList());
System.out.println("先按工资再按年龄自定义排序(降序):" + nameList3);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
提取/组合
流也可以进行合并(concat)、去重(distinct)、限制(limit)、跳过(skip)等操作。

String[] arr1 = {"a", "b", "c", "d"};
String[] arr2 = {"d", "e", "f", "g"};

Stream<String> stream1 = Stream.of(arr1);
Stream<String> stream2 = Stream.of(arr2);

// concat:合并两个流 distinct:去重
List<String> stringList = Stream.concat(stream1, stream2).distinct().collect(Collectors.toList());
System.out.println("流合并:" + stringList);
// limit:限制从流中获得前n个数据
List<Integer> integerList = Stream.iterate(1, x -> x + 2).limit(10).collect(Collectors.toList());
System.out.println("limit:" + integerList);
// skip:跳过前n个数据
List<Integer> integerList1 = Stream.iterate(1, x -> x + 2).skip(1).limit(5).collect(Collectors.toList());
System.out.println("skip:" + integerList1);
————————————————
版权声明:本文为CSDN博主「阳光下的米雪」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_38530648/article/details/114270058

标签:Stream,Collectors,stream,Person,--,collect,println,personList
来源: https://www.cnblogs.com/ExMan/p/16386495.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有