public static List<User> getUserList() {
List<User> users = new ArrayList<>();
users.add(new User("1", "name1", "Java组", 33, "男", new BigDecimal("25000"), true));
users.add(new User("2", "name2", "Java组", 31, "女", new BigDecimal("28000"), true));
users.add(new User("3", "name3", "前端组", 33, "男", new BigDecimal("18000"), true));
users.add(new User("4", "name4", "前端组", 25, "男", new BigDecimal("19000"), false));
users.add(new User("5", "name5", "QA组", 24, "女", new BigDecimal("15000"), true));
users.add(new User("6", "name6", "产品组", 34, "女", new BigDecimal("12000"), true));
return users;
}
Map<String, List<User>> collect = users.stream().collect(
Collectors.groupingBy(
User::getDept
)
);
Map<String, List<User>> groupByDeptAppendName = users.stream().collect(
Collectors.groupingBy(
user -> user.getDept() + "&" + user.getName()
)
);
Map<String, Map<String, List<User>>> groupByDeptAndGender = users.stream()
.filter(user -> Objects.nonNull(user.getSex())) // group by 的字段不能有null值
.collect(
Collectors.groupingBy(
User::getDept,
Collectors.groupingBy(User::getSex)
)
);
Map<String, List<String>> collect = users.stream().collect(
Collectors.groupingBy(
User::getDept,
Collectors.mapping(
User::getId,
Collectors.toList()
)
)
);
{Java组=[1, 2], QA组=[5], 前端组=[3, 4], 产品组=[6]}
Map<String, Long> groupBuyDeptThenCount = users.stream().collect(
Collectors.groupingBy(
User::getDept,
Collectors.counting()
)
);
Map<String, Set<String>> collect = users.stream().collect(
Collectors.groupingBy(
User::getDept,
Collectors.mapping(
User::getSex,
Collectors.toSet()
)
)
);
{Java组=[女, 男], QA组=[女], 前端组=[男], 产品组=[女]}
Collectors.collectingAndThen()
它接受两个参数:downstream
和finisher
。其中
downstream
是一个Collector收集器,用于对数据流中的元素进行收集操作;finisher
是一个Function函数,用于对downstream
的收集结果进行处理,并返回最终的结果。Map<String, Integer> collect = users.stream().collect(
Collectors.groupingBy(
User::getDept,
Collectors.collectingAndThen(
Collectors.mapping(
User::getSex,
Collectors.toSet()
),
a -> a.size()
)
)
);
{Java组=2, QA组=1, 前端组=1, 产品组=1}
Map<Boolean, List<User>> collect = users.stream().collect(
Collectors.partitioningBy(
a -> a.getAge() > 30
)
);
Map<String, User> userMap = users.stream().collect(
Collectors.toMap(
User::getId,
Function.identity(),
(k1, k2) -> k1 //key重复,用第一个
)
);
Map<String, String> idToName = users.stream().collect(
Collectors.toMap(
User::getId,
User::getName
)
);
求年龄最大的人:
Optional<User> maxAgeUserOptional = users.stream().collect(
Collectors.maxBy(Comparator.comparing(User::getAge))
);
求年龄最小的人:
Optional<User> minAgeUserOptional = users.stream().collect(
Collectors.minBy(Comparator.comparing(User::getAge))
);
求最大的年龄:
int maxAge = users.stream().mapToInt(User::getAge).max().getAsInt();
求最小的年龄:
int minAge = users.stream().mapToInt(User::getAge).min().getAsInt();
求年龄总和:
int sumAge = users.stream().mapToInt(User::getAge).sum();
求平均年龄:
double avgAge = users.stream().mapToInt(User::getAge).average().getAsDouble();
Map<String, User> groupByDeptThenGetMaxAgeUser = users.stream().collect(
Collectors.groupingBy(
User::getDept,
Collectors.collectingAndThen(
Collectors.maxBy(
Comparator.comparing(
User::getAge,
Comparator.nullsLast(Integer::compareTo)
)
),
Optional::get
)
)
);
Map<String, Integer> collect = users.stream().collect(
Collectors.groupingBy(
User::getDept,
Collectors.collectingAndThen(
Collectors.maxBy(
Comparator.comparingInt(User::getAge)
),
a -> a.isPresent() ? a.get().getAge() : null
)
)
);
Map<String, Double> collect = users.stream().collect(
Collectors.groupingBy(
User::getDept,
Collectors.averagingInt(User::getAge)
)
);
Map<String, Integer> collect = users.stream().collect(
Collectors.groupingBy(
User::getDept,
Collectors.summingInt(User::getAge)
)
);
Map<String, IntSummaryStatistics> collect = users.stream().collect(
Collectors.groupingBy(
User::getDept,
Collectors.summarizingInt(
User::getAge
)
)
);
for (Map.Entry<String, IntSummaryStatistics> entry : collect.entrySet()) {
IntSummaryStatistics summaryStatistics = entry.getValue();
System.out.println("----------------key----------------" + entry.getKey());
System.out.println("求和:" + summaryStatistics.getSum());
System.out.println("求平均" + summaryStatistics.getAverage());
System.out.println("求最大:" + summaryStatistics.getMax());
System.out.println("求最小:" + summaryStatistics.getMin());
System.out.println("求总数:" + summaryStatistics.getCount());
}
List<BigDecimal> userSalary = users.stream().map(User::getSalary).collect(Collectors.toList());
Optional<BigDecimal> maxSalary = userSalary.stream().reduce(BigDecimal::max);
Optional<BigDecimal> minSalary = userSalary.stream().reduce(BigDecimal::min);
BigDecimal sumSalary = userSalary.stream().reduce(BigDecimal.ZERO, BigDecimal::add);
BigDecimal avgSalary= sumSalary.divide(BigDecimal.valueOf(userSalary.size()), 2, BigDecimal.ROUND_HALF_UP);
Map<String, BigDecimal> groupByDeptThenGetMaxSalary = users.stream().collect(
Collectors.groupingBy(
User::getDept,
Collectors.reducing(
BigDecimal.ZERO,
User::getSalary,
BigDecimal::max
)
)
);
Map<String, BigDecimal> groupByDeptThenGetMinSalary = users.stream().collect(
Collectors.groupingBy(
User::getDept,
Collectors.reducing(
BigDecimal.valueOf(Long.MAX_VALUE),
User::getSalary,
BigDecimal::min
)
)
);
如果考虑Salary有null值,可以如下处理
Map<String, BigDecimal> groupByDeptThenGetMinSalary = users.stream().collect(
Collectors.groupingBy(
User::getDept,
Collectors.collectingAndThen(
Collectors.reducing(
(c1, c2) -> c1.getSalary().compareTo(c2.getSalary()) > 0 ? c2 : c1
),
a -> a.isPresent() ? a.get().getSalary() : null
)
)
);
Map<String, BigDecimal> groupByDeptThenGetSumSalary = users.stream()
.filter(user -> Objects.nonNull(user.getDept())) //比较的字段不能有null值
.collect(
Collectors.groupingBy(
User::getDept,
Collectors.reducing(
BigDecimal.ZERO,
User::getSalary,
BigDecimal::add
)
)
);
Collectors
中有averagingInt、averagingLong、averagingDouble
等,但是没有averagingBigDecimal
。
参考java lambada 对list进行分组汇总,实现自定义averagingBigDecimal
Map<String, BigDecimal> groupByDeptThenGetAvgSalary = users.stream()
.filter(user -> Objects.nonNull(user.getDept())) //比较的字段不能有null值
.collect(
Collectors.groupingBy(
User::getDept,
CustomCollectors.averagingBigDecimal(User::getSalary, 2, 2)
)
);