文章16 | 阅读 6548 | 点赞0
集合的stream()方法是将集合转换为流形式以处理数据, Stream的collect 是将流转换为集合或其它形式存储流运算结果. Collector 接口中方法的实现决定了如何对流执行收集操作,但并非一定要自己去实现此接口, Collectors 实现类提供了很多静态方法, 可以便捷地创建收集器实例.
测试数据如下:
static List<Employee> emps = new ArrayList<>();
static {
emps.add(new Employee(1001, "张三", "Man", 50));
emps.add(new Employee(1002, "李四", "Man", 30));
emps.add(new Employee(1003, "王五", "Woman", 25));
emps.add(new Employee(1004, "赵六", "Man", 35));
emps.add(new Employee(1005, "小七", "Woman", 30));
emps.add(new Employee(1006, "周八", "Man", 42));
}
将流元素收集到ArrayList 中.
// 将处理后的流中所有元素收集到list中,list 为 java.util.ArrayList
@Test
public void test_toList(){
List<String> list = emps.stream()
.filter((employee -> "Woman".equals(employee.getSex())))
.map((employee -> employee.getName()))
.collect(Collectors.toList());
list.forEach(System.out::println);
System.out.println(list.getClass());
}
将流元素收集到HashSet 中
// 将处理后的流中所有元素收集到Set 中, Set为 java.util.HashSet
@Test
public void test_toSet(){
Set<String> set = emps.stream()
.filter((employee -> "Man".equals(employee.getSex())))
.map((employee -> employee.getName()))
.collect(Collectors.toSet());
set.forEach(System.out::println);
System.out.println(set.getClass());
}
将流元素收集到自定义容器中
// 自定义集合数据结构
@Test
public void test_toCollection(){
Set<String> set = emps.stream()
.filter((employee -> "Man".equals(employee.getSex())))
.map((employee -> employee.getName()))
.collect(Collectors.toCollection(LinkedHashSet::new));
System.out.println(set.getClass());
}
计算流中元素个数
//获取流中元素总数量
@Test
public void test_counting(){
Long total = emps.stream().collect(Collectors.counting());
System.out.println("流中元素总数量: " + total);
}
聚合操作, 包含: counting(), maxBy(), minBy(), summingInt(), averagingInt(), summingLong(), averagingLong(), summingDouble(), averagingDouble() 等API
// 测试聚合函数
@Test
public void test_aggregation(){
Long count = emps.stream().collect(Collectors.counting());
Integer sum = emps.stream().collect(Collectors.summingInt(Employee::getAge));
Double average = emps.stream().collect(Collectors.averagingInt(Employee::getAge));
Optional<Employee> maxOp = emps.stream().collect(Collectors.maxBy((e1, e2) -> e1.getAge().compareTo(e2.getAge())));
Optional<Employee> minOp = emps.stream().collect(Collectors.minBy((e1, e2) -> e1.getAge().compareTo(e2.getAge())));
System.out.println("员工列表中男性总数量: " + count);
System.out.println("员工列表中男性总年龄: " + sum);
System.out.println("员工列表中男性平均年龄: " + average);
System.out.println("员工列表中男性最大年龄: " + maxOp.get());
System.out.println("员工列表中平均年龄: " + minOp.get());
}
// 对Int类型做聚合运算,形似API 还有summarizingDouble, summarizingLong
@Test
public void test_summarizingInt(){
// 对于自定义对象流,可使用collect 获取*statistics 聚合函数信息, 对于特定流 Int/Double/LongStream, 提供了对应的方法
IntSummaryStatistics statistics = emps.stream()
.filter((employee -> "Man".equals(employee.getSex())))
.collect(Collectors.summarizingInt(Employee::getAge));
System.out.println("员工列表中男性总数量: " + statistics.getCount());
System.out.println("员工列表中男性总年龄: " + statistics.getSum());
System.out.println("员工列表中男性平均年龄: " + statistics.getAverage());
System.out.println("员工列表中男性最大年龄: " + statistics.getMax());
System.out.println("员工列表中平均年龄: " + statistics.getMin());
DoubleSummaryStatistics dbStatistics = DoubleStream.of(10.0, 15.5, 20.5, 31.5, 40.0).summaryStatistics();
System.out.println("流中元素总数量:" + dbStatistics.getCount());
System.out.println("流中元素总和:" + dbStatistics.getSum());
System.out.println("流中元素平均值:" + dbStatistics.getAverage());
System.out.println("流中元素最大值:" + dbStatistics.getMax());
System.out.println("流中元素最小值:" + dbStatistics.getMin());
}
将流中元素进行分组
// 分组函数: 可进行一级或多级分组, 返回为map 结构
@Test
public void test_groupingBy(){
// 一级分组: 按性别分组
Map<String, List<Employee>> sexMap = emps.stream().collect(Collectors.groupingBy(Employee::getSex));
// 而二级分组: 先按性别分组, 再按年龄分组
Map<String, Map<String, List<Employee>>> map = emps.stream()
.collect(Collectors.groupingBy(Employee::getSex,
Collectors.groupingBy((employee) -> {
if (employee.getAge() < 20) {
return "青年";
} else if (employee.getAge() < 40) {
return "中年";
} else {
return "老年";
}
})));
System.out.println(sexMap);
System.out.println(map);
}
将流中元素进行分区.
// 分区,按照是否满足条件分为两组, 可嵌套分组
@Test
public void test_partitional(){
// 一级分组
Map<Boolean, List<Employee>> map1 = emps.stream()
.collect(Collectors.partitioningBy((employee) -> employee.getAge() > 30));
System.out.println("年龄大于30岁的: " + map1.get(true));
System.out.println("年龄小于30岁的: " + map1.get(false));
System.out.println("----------------------------------------------------------------------------------");
// 多机分组
Map<Boolean, Map<Boolean, List<Employee>>> map2 = emps.stream()
.collect(Collectors.partitioningBy((employee) -> employee.getAge() > 30,
Collectors.partitioningBy((employee) -> "Man".equals(employee.getSex()))));
System.out.println("年龄大于30岁的男性: " + map2.get(true).get(true));
System.out.println("年龄大于30岁的女性: " + map2.get(true).get(false));
System.out.println("年龄小于30岁的男性: " + map2.get(false).get(true));
System.out.println("年龄小于30岁的女性: " + map2.get(false).get(false));
}
对流中元素进行字符串拼接.
// 拼接字符串
@Test
public void test_join(){
String names = emps.stream()
.map((employee -> employee.getName()))
.collect(Collectors.joining(",", "(", ")"));
System.out.println(names);
}
对流中元素做迭代式运算.
// reducing 对流中元素做聚合运算, 类似于stream.reduce()
@Test
public void test_reducing(){
Integer sum = emps.stream().collect(Collectors.reducing(0, Employee::getAge, Integer::sum));
System.out.println(sum);
}
包裹另外一个收集器, 对其结果做转换函数.
// 包含另外一个收集器
@Test
public void test_collectingAndThen(){
Integer size = emps.stream().collect(Collectors.collectingAndThen(Collectors.toList(), List::size));
System.out.println(size);
}
版权说明 : 本文为转载文章, 版权归原作者所有 版权申明
原文链接 : https://zongf.blog.csdn.net/article/details/90057623
内容来源于网络,如有侵权,请联系作者删除!