Stream API 对两个 List 进行去重操作

在 Java 8 及以上版本中,可以使用 Lambda 表达式和 Stream API 对两个 List 进行去重操作。以下是几种常见的去重场景及对应的 Lambda 表达式实现方式:

1. 合并两个 List 并去重

java 复制代码
List<String> list1 = Arrays.asList("A", "B", "C");
List<String> list2 = Arrays.asList("B", "C", "D");

// 合并并去重(使用 Stream.concat + distinct)
List<String> distinctList = Stream.concat(list1.stream(), list2.stream())
                                  .distinct()
                                  .collect(Collectors.toList());

System.out.println(distinctList); // [A, B, C, D]

2. 取两个 List 的交集(保留重复元素)

java 复制代码
List<String> list1 = Arrays.asList("A", "B", "B", "C");
List<String> list2 = Arrays.asList("B", "C", "C", "D");

// 取交集(保留重复元素)
List<String> intersection = list1.stream()
                                .filter(list2::contains)
                                .collect(Collectors.toList());

System.out.println(intersection); // [B, B, C]

3. 取两个 List 的交集(去重)

java 复制代码
List<String> list1 = Arrays.asList("A", "B", "B", "C");
List<String> list2 = Arrays.asList("B", "C", "C", "D");

// 取交集(去重)
List<String> distinctIntersection = list1.stream()
                                        .filter(list2::contains)
                                        .distinct()
                                        .collect(Collectors.toList());

System.out.println(distinctIntersection); // [B, C]

4. 取两个 List 的差集(list1 有但 list2 没有)

java 复制代码
List<String> list1 = Arrays.asList("A", "B", "C");
List<String> list2 = Arrays.asList("B", "C", "D");

// list1 有但 list2 没有的元素(去重)
List<String> difference = list1.stream()
                              .filter(e -> !list2.contains(e))
                              .collect(Collectors.toList());

System.out.println(difference); // [A]

5. 合并两个 List 并去重(自定义对象去重)

如果 List 里存放的是自定义对象(如 User),需要重写 equals()hashCode() 方法,然后使用 distinct() 去重:

java 复制代码
class User {
    private String name;
    private int age;

    // 构造方法、getter、setter 省略

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        User user = (User) o;
        return age == user.age && Objects.equals(name, user.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, age);
    }
}

// 测试
List<User> list1 = Arrays.asList(new User("Alice", 20), new User("Bob", 25));
List<User> list2 = Arrays.asList(new User("Bob", 25), new User("Charlie", 30));

List<User> distinctUsers = Stream.concat(list1.stream(), list2.stream())
                                .distinct()
                                .collect(Collectors.toList());

distinctUsers.forEach(u -> System.out.println(u.getName())); // Alice, Bob, Charlie

6. 使用 Set 去重(更高效)

如果只是单纯去重,可以先把 List 转成 Set(自动去重),再转回 List

java 复制代码
List<String> list = Arrays.asList("A", "B", "B", "C");
List<String> distinctList = new ArrayList<>(new HashSet<>(list));

System.out.println(distinctList); // [A, B, C](顺序可能变化)

7、总结

场景 方法
合并两个 List 并去重 Stream.concat(list1.stream(), list2.stream()).distinct()
取交集(保留重复) list1.stream().filter(list2::contains).collect(Collectors.toList())
取交集(去重) list1.stream().filter(list2::contains).distinct().collect(Collectors.toList())
取差集(list1 有但 list2 没有) list1.stream().filter(e -> !list2.contains(e)).collect(Collectors.toList())
自定义对象去重 重写 equals()hashCode(),再用 distinct()

选择合适的方式取决于你的具体需求(是否保留顺序、是否需要高性能等)。

相关推荐
luoyayun36119 分钟前
实现Windows系统标题栏颜色跟随主题动态切换
windows·系统标题栏颜色·标题栏颜色
爱敲代码的TOM1 小时前
数据结构总结
数据结构
猫头虎1 小时前
如何解决 OpenClaw “Pairing required” 报错:两种官方解决方案详解
网络·windows·网络协议·macos·智能路由器·pip·scipy
皮皮哎哟3 小时前
数据结构:嵌入式常用排序与查找算法精讲
数据结构·算法·排序算法·二分查找·快速排序
堕2743 小时前
java数据结构当中的《排序》(一 )
java·数据结构·排序算法
2302_813806224 小时前
【嵌入式修炼:数据结构篇】——数据结构总结
数据结构
Wei&Yan4 小时前
数据结构——顺序表(静/动态代码实现)
数据结构·c++·算法·visual studio code
呉師傅4 小时前
【使用技巧】Adobe Photoshop 2024调整缩放与布局125%后出现点菜单项漂移问题的简单处理
运维·服务器·windows·adobe·电脑·photoshop
long3165 小时前
Aho-Corasick 模式搜索算法
java·数据结构·spring boot·后端·算法·排序算法
梦帮科技6 小时前
OpenClaw 桥接调用 Windows MCP:打造你的 AI 桌面自动化助手
人工智能·windows·自动化