文章首发于个人博客,欢迎访问关注:https://www.lin2j.tech
辅助类
@Data
@AllArgsConstructor
public class User {
private String name;
private Integer age;
}
groupingBy()
– 分组
Java8
中的 groupingBy
实现集合的分组,类似于 Mysql
中的 group by
操作,返回一个 Map
。
package com.jia.blogdemo.stream;
/**
* @author linjinjia linjinjia047@163.com
* @date 2021/4/1 18:10
*/
public class GroupByDemo {
public static void main(String[] args) {
List<User> users = new ArrayList<>();
users.add(new User("a", 12));
users.add(new User("a", 14));
users.add(new User("a", 12));
users.add(new User("b", 12));
users.add(new User("b", 12));
users.add(new User("b", 14));
// 对集合的元素按照某一个字段进行分组
groupByOnField(users);
// 对集合的多个字段同时作为分组条件
groupByMultiField1(users);
// 对集合的多个字段先后进行分组
groupByMultiField2(users);
}
}
场景一:只对一个字段进行分组
private static void groupByOnField(List<User> users) {
Map<String, List<User>> map =
users.stream().collect(Collectors.groupingBy(User::getName));
System.out.println(map);
}
输出:
{a=[User(name=a, age=12), User(name=a, age=14), User(name=a, age=12)], b=[User(name=b, age=12), User(name=b, age=12), User(name=b, age=14)]}
debug
截图
场景二:两个字段结合起来,作为分组条件
private static void groupByMultiField1(List<User> users) {
Map<String, List<User>> map =
users.stream().collect(Collectors.groupingBy(GroupByDemo::groupString));
System.out.println(map);
}
private static String groupString(User user) {
return user.getName() + user.getAge();
}
输出:
{b12=[User(name=b, age=12), User(name=b, age=12)], a12=[User(name=a, age=12), User(name=a, age=12)], b14=[User(name=b, age=14)], a14=[User(name=a, age=14)]}
场景三:先对某一个字段分组,然后再将各组内的元素按照另一个字段分组
private static void groupByMultiField2(List<User> users) {
Map<String, Map<Integer, List<User>>> map =
users.stream().collect(Collectors.groupingBy(User::getName, Collectors.groupingBy(User::getAge)));
System.out.println(map);
System.out.println(map.get("a").get(12).get(0));
}
输出:
{a={12=[User(name=a, age=12), User(name=a, age=12)], 14=[User(name=a, age=14)]}, b={12=[User(name=b, age=12), User(name=b, age=12)], 14=[User(name=b, age=14)]}}
User(name=a, age=12)
debug
截图
partitioningBy()
– 分区
partitioningBy()
是根据断言,然后将集合分为两部分,true
和 false
,操作返回 Map
。
package com.jia.blogdemo.stream;
/**
* @author linjinjia linjinjia047@163.com
* @date 2021/4/1 22:08
*/
public class PartitioningByDemo {
public static void main(String[] args) {
List<User> users = new ArrayList<>();
users.add(new User("a", 12));
users.add(new User("b", 13));
users.add(new User("c", 14));
users.add(new User("e", 15));
users.add(new User("f", 16));
users.add(new User("g", 17));
partitioningByOneField(users);
partitioningAndCount(users);
}
/**
* 场景一:为某个字段设置断言,分为两个组合
*/
private static void partitioningByOneField(List<User> user) {
Map<Boolean, List<User>> map =
user.stream().collect(Collectors.partitioningBy(u -> u.getAge() > 15));
System.out.println(map);
}
/**
* 场景二:为某个字段设置断言,分为两个组合,然后统计两个组合的元素个数
*/
private static void partitioningAndCount(List<User> users) {
Map<Boolean, Long> map =
users.stream().collect(Collectors.partitioningBy(u -> u.getAge() > 15, Collectors.counting()));
System.out.println(map);
}
}
场景一:为某个字段设置断言,分为两个组合
private static void partitioningByOneField(List<User> user) {
Map<Boolean, List<User>> map =
user.stream().collect(Collectors.partitioningBy(u -> u.getAge() > 15));
System.out.println(map);
}
输出:
{false=[User(name=a, age=12), User(name=b, age=13), User(name=c, age=14), User(name=e, age=15)], true=[User(name=f, age=16), User(name=g, age=17)]}
场景二:为某个字段设置断言,分为两个组合,然后统计两个组合的元素个数
private static void partitioningAndCount(List<User> users) {
Map<Boolean, Long> map =
users.stream().collect(Collectors.partitioningBy(u -> u.getAge() > 15, Collectors.counting()));
System.out.println(map);
}
输出:
{false=4, true=2}