You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java 11 Lambda按ID分组后优先筛选PROPERTY为A的实体实现方案

解决思路:用Stream groupingBy + 自定义收集器

嘿,这个需求用Java Stream API完全能搞定,你选groupingBy的思路是对的,关键是搭配合适的收集器来处理每个分组内的元素——我们的目标是优先保留PROPERTY为"A"的实体,如果组里没有"A"才保留"Z"。

先明确实体类(假设你有这样的类)

首先定义一下我们操作的实体类,方便后续代码示例:

class Entity {
    private String id;
    private String property;

    // 构造器、getter方法
    public Entity(String id, String property) {
        this.id = id;
        this.property = property;
    }

    public String getId() { return id; }
    public String getProperty() { return property; }

    // 重写toString方便查看结果
    @Override
    public String toString() {
        return id + " | " + property;
    }
}

方案1:用collectingAndThen + 过滤查找

这种方式逻辑最直观:先按ID分组,对每个分组的元素列表,先筛选出"A"的实体,找到第一个就返回;如果没有,再筛选"Z"的实体返回。

import java.util.*;
import java.util.stream.Collectors;

public class Main {
    public static void main(String[] args) {
        List<Entity> list = Arrays.asList(
            new Entity("FOO", "A"),
            new Entity("FOO", "Z"),
            new Entity("JOHN", "A"),
            new Entity("DOE", "Z")
        );

        List<Entity> result = list.stream()
            .collect(Collectors.groupingBy(Entity::getId,
                Collectors.collectingAndThen(
                    Collectors.toList(),
                    entities -> entities.stream()
                        .filter(e -> "A".equals(e.getProperty()))
                        .findFirst()
                        .orElseGet(() -> entities.stream()
                            .filter(e -> "Z".equals(e.getProperty()))
                            .findFirst()
                            .orElse(null)) // 可根据业务调整,比如抛异常
                )
            ))
            .values()
            .stream()
            .filter(Objects::nonNull)
            .collect(Collectors.toList());

        // 打印结果
        result.forEach(System.out::println);
    }
}

方案2:用maxBy + 自定义比较器(更简洁)

我们可以给"A"设置更高的优先级,用maxBy收集器来选出分组内优先级最高的实体:

List<Entity> result = list.stream()
    .collect(Collectors.groupingBy(Entity::getId,
        Collectors.maxBy(Comparator.comparing(e -> "A".equals(e.getProperty()) ? 1 : 0))
    ))
    .values()
    .stream()
    .filter(Optional::isPresent)
    .map(Optional::get)
    .collect(Collectors.toList());

这里的逻辑是:给PROPERTY为"A"的实体赋值优先级1,"Z"赋值0,maxBy会自动选出优先级更高的实体;如果分组里没有"A",就会选"Z"的实体。

运行结果

两种方案运行后都会输出你期望的结果:

FOO | A
JOHN | A
DOE | Z

内容的提问来源于stack exchange,提问作者Fabrizio Stellato

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 14:17:52