Java:如何使用 Stream API 按条件对实体进行分组?

标签 java group-by streaming java-stream

我有一个用户列表。

class User {
    String name;
}

我需要按名称对用户进行分组。

List<Set<User>> groupedBy;

分组条件是名称相似度,是一些Comparator

Comparator<User> p = new Comparator<User>() {
    // some comparison logic
};

如何使用 Java 8 流按相似名称对用户进行分组?

我尝试使用分区,但它的 API 与我需要的不同。

Map<Boolean, List<User>> collected = users.stream().collect(Collectors.partitioningBy(new Predicate<User>() {
    @Override
    public boolean test(User user) {
        // ...
    }
}, Collectors.toList()));

最佳答案

通常,如果您想通过简单的属性进行分组,您可以使用

Map<String,Set<User>> m=users.stream()
    .collect(Collectors.groupingBy(User::getName, Collectors.toSet()));

但是,如果您有一个复杂的逻辑,表示为现有的Comparator,例如

Comparator<User> comparator=Comparator.comparing(u -> u.getName(), Collator.getInstance());

你可以使用

Map<User,Set<User>> m=users.stream().collect(
    Collectors.groupingBy(u -> u, () -> new TreeMap<>(comparator), Collectors.toSet()));

根据比较器中封装的逻辑进行分组。

在这两种情况下,您都会获得一个Map,可以使用它转换为您想要的列表

List<Set<User>> groupedBy = new ArrayList<>(m.values());

您还可以将最后一步表示为Collector的一部分,例如

List<Set<User>> groupedBy=users.stream().collect(
    Collectors.collectingAndThen(
        Collectors.groupingBy(u -> u, () -> new TreeMap<>(comparator), Collectors.toSet()),
        m -> new ArrayList<Set<User>>(m.values())));

关于Java:如何使用 Stream API 按条件对实体进行分组?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42516470/

相关文章:

Django:将值从模板传递到 View

javascript - 可以进行客户端 HTTP 推送吗?

Java:按位AND创建无符号字节

java - BAPI_PERSDATA_CHANGE 使用 SAP JCo 3 更新用户数据

sql - 使用联接对多列进行累积总和

mysql - 同时获取每列中每个值的计数

mysql - GROUP BY 一列和 COUNT 两列

streaming - 限制 gstreamer 管道吞吐量以模拟实时源

java - Win2003终端服务器的Applet加载问题

java - Hadoop 中的 setJarByClass()