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

如何使用Java Stream移除一个列表中存在于另一个列表的自定义对象元素

解决方案

前置准备

默认Java对象是按内存地址判断是否相等,如果你认为id相同的Car就是同一个对象,需要先明确相等判断规则,可选择重写Car类的equals和hashCode方法,示例如下:

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

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

如果不需要修改原cars1列表,推荐用Stream生成新的过滤后列表,同时为了优化查找性能,建议先把cars2的元素(或唯一标识)转为Set,将查找复杂度从O(n)降到O(1)。

实现方案

方案1:基于唯一标识过滤(性能最优,不需要重写equals/hashCode)

直接通过Car的id判断是否存在,无需修改Car类代码:

// 先提取cars2所有Car的id存入Set,方便快速查找
Set<Integer> car2IdSet = cars2.stream()
        .map(car -> car.id)
        .collect(Collectors.toSet());

// Stream过滤cars1,保留不在cars2里的元素,生成新列表
List<Car> filteredCars = cars1.stream()
        .filter(car -> !car2IdSet.contains(car.id))
        .collect(Collectors.toList());

如果需要覆盖原cars1变量,直接赋值即可:cars1 = filteredCars;

方案2:基于对象本身判断(需要先重写equals和hashCode)

如果需要按自定义的对象相等规则判断,可直接将cars2转为Set后过滤:

Set<Car> car2Set = new HashSet<>(cars2);

List<Car> filteredCars = cars1.stream()
        .filter(car -> !car2Set.contains(car))
        .collect(Collectors.toList());

注意事项

不推荐直接在filter中使用cars2::contains判断,当cars2数据量较大时,每次遍历判断的性能会非常差,提前转Set是更合理的选择。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 08:06:01