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

如何用Java Stream更简洁实现去重列表?无需手动实例化集合

优化Java Stream去重列表的简洁写法

当然有更简洁高效的写法,完全不用手动创建ArrayList和显式return列表,而且性能比你当前的实现好很多,以下分几种场景给出方案:


场景1:可以修改BeanLevel类

如果能给BeanLevel重写equals()和hashCode()方法(基于id判断相等),直接用Stream自带的distinct()方法即可:

public static List<BeanLevel> sniff(List<BeanTask> tasks) {
    return tasks.stream()
                .map(task -> task.level) // 或者用BeanTask::getLevel(如果有getter方法)
                .distinct()
                .collect(Collectors.toList());
}

重写BeanLevel的equals和hashCode示例:

@Override
public boolean equals(Object o) {
    if (this == o) return true;
    if (o == null || getClass() != o.getClass()) return false;
    BeanLevel beanLevel = (BeanLevel) o;
    return id == beanLevel.id;
}

@Override
public int hashCode() {
    return Objects.hash(id);
}

场景2:不能修改BeanLevel类

如果无法修改BeanLevel的源码,用Collectors.toMap利用Map键的唯一性实现去重:

public static List<BeanLevel> sniff(List<BeanTask> tasks) {
    return tasks.stream()
                .map(task -> task.level)
                .collect(Collectors.toMap(
                    BeanLevel::getId,       // 用id作为Map的键
                    level -> level,         // 用level本身作为值
                    (existing, newLevel) -> existing // 遇到重复键时保留已存在的对象
                ))
                .values()                  // 取出所有去重后的level
                .stream()
                .collect(Collectors.toList());
}

这种写法全程用Stream操作串联,无需手动创建集合和添加元素,时间复杂度为O(n),比你原来每次遍历列表检查的O(n²)性能提升显著。

另外还有一种更轻量的写法,用HashSet跟踪已见过的id:

public static List<BeanLevel> sniff(List<BeanTask> tasks) {
    Set<Long> seenIds = new HashSet<>();
    return tasks.stream()
                .map(task -> task.level)
                .filter(level -> seenIds.add(level.getId())) // add返回false则过滤重复项
                .collect(Collectors.toList());
}

原实现的问题

你原来的代码在forEach中每次检查level是否存在时,都要遍历整个lst,数据量大时性能会很差;而上面的优化方案都是基于哈希表的O(1)查找,既简洁又高效,完全符合Stream的函数式编程风格。

内容的提问来源于stack exchange,提问作者Tugalsan Karabacak

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 12:39:51