当前位置: 首页 > article >正文

Java 中求两个 List集合的交集元素

在 Java 中,求两个 List 的交集元素可以通过多种方式实现。常见的做法包括使用 retainAll 方法、Stream API 或手动遍历。以下是这些方法的原理和实现:

1. 使用 retainAll 方法

retainAllCollection 接口中的一个方法,用于保留集合中与指定集合相同的元素,移除其他元素。

原理:
  • retainAll 方法会遍历当前集合,并检查每个元素是否存在于指定集合中。
  • 如果元素不存在于指定集合中,则从当前集合中移除该元素。
  • 最终,当前集合只保留与指定集合相同的元素。

retainAll 是 Java 中 List 接口提供的一个方法,用于保留列表中与指定集合中相同的元素,移除其他所有元素。换句话说,retainAll 方法会修改当前列表,使其仅包含与指定集合中相同的元素。


方法定义
boolean retainAll(Collection<?> c);
参数:
  • c:包含需要保留元素的集合。
返回值:
  • 如果列表因调用此方法而发生变化,则返回 true
  • 如果列表未发生变化(即列表已经只包含指定集合中的元素),则返回 false

方法行为
  1. 保留交集retainAll 方法会保留当前列表与指定集合的交集。
  2. 移除其他元素:当前列表中不在指定集合中的元素会被移除。
  3. 修改原列表retainAll 方法会直接修改当前列表,而不是返回一个新的列表。

示例代码

以下是一个简单的示例,展示 retainAll 方法的使用:

import java.util.ArrayList;
import java.util.List;

public class RetainAllExample {
    public static void main(String[] args) {
        // 创建两个列表
        List<String> list1 = new ArrayList<>();
        list1.add("Apple");
        list1.add("Banana");
        list1.add("Cherry");
        list1.add("Date");

        List<String> list2 = new ArrayList<>();
        list2.add("Banana");
        list2.add("Date");
        list2.add("Fig");

        // 调用 retainAll 方法
        boolean isChanged = list1.retainAll(list2);

        // 输出结果
        System.out.println("List1 是否发生变化: " + isChanged); // true
        System.out.println("List1 的内容: " + list1); // [Banana, Date]
        System.out.println("List2 的内容: " + list2); // [Banana, Date, Fig]
    }
}
输出:
List1 是否发生变化: true
List1 的内容: [Banana, Date]
List2 的内容: [Banana, Date, Fig]

关键点
  1. 修改原列表

    • retainAll 方法会直接修改调用它的列表,而不是返回一个新的列表。
    • 如果需要保留原列表,可以在调用 retainAll 之前创建一个副本。
  2. 返回值

    • 如果列表因调用 retainAll 而发生变化,则返回 true
    • 如果列表未发生变化(即列表已经只包含指定集合中的元素),则返回 false
  3. 集合比较

    • retainAll 方法依赖于 equals 方法来比较元素是否相同。
    • 如果集合中包含自定义对象,请确保正确重写了 equalshashCode 方法。
  4. 空集合

    • 如果传入的集合为空(null 或空集合),retainAll 会抛出 NullPointerException 或清空当前列表。

注意事项

  1. 性能问题

    • retainAll 方法的时间复杂度取决于列表的实现。对于 ArrayList,时间复杂度为 O(n*m),其中 n 是列表的大小,m 是集合的大小。
    • 如果列表和集合都很大,性能可能会受到影响。
  2. 集合类型

    • retainAll 方法可以接受任何实现了 Collection 接口的对象作为参数,例如 ListSet 等。
  3. 元素重复

    • 如果列表中有重复元素,而指定集合中没有重复元素,retainAll 会保留列表中的重复元素。
    • 例如:
      List<String> list1 = new ArrayList<>(List.of("A", "A", "B", "C"));
      List<String> list2 = new ArrayList<>(List.of("A", "B"));
      list1.retainAll(list2);
      System.out.println(list1); // 输出 [A, A, B]
      

注:
  • retainAll 方法用于保留列表中与指定集合中相同的元素,移除其他元素。
  • 它会直接修改原列表,并返回一个布尔值表示列表是否发生变化。
  • 使用时需要注意性能问题和集合类型的兼容性。
  • 如果需要保留原列表,可以在调用 retainAll 之前创建一个副本。

2. 使用 Stream API

Java 8 引入了 Stream API,可以方便地对集合进行操作。

原理:
  • 使用 stream() 方法将 List 转换为流。
  • 使用 filter 方法过滤出存在于另一个集合中的元素。
  • 使用 collect 方法将结果收集到一个新的 List 中。
示例代码:
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

public class Main {
    public static void main(String[] args) {
        List<Integer> list1 = new ArrayList<>();
        list1.add(1);
        list1.add(2);
        list1.add(3);

        List<Integer> list2 = new ArrayList<>();
        list2.add(2);
        list2.add(3);
        list2.add(4);

        List<Integer> intersection = list1.stream()
                .filter(list2::contains)
                .collect(Collectors.toList());

        System.out.println(intersection); // 输出: [2, 3]
    }
}

3. 手动遍历

手动遍历两个 List,并找出共同的元素。

原理:
  • 遍历第一个 List 中的每个元素。
  • 检查该元素是否存在于第二个 List 中。
  • 如果存在,则将其添加到结果集合中。
示例代码:
import java.util.ArrayList;
import java.util.List;

public class Main {
    public static void main(String[] args) {
        List<Integer> list1 = new ArrayList<>();
        list1.add(1);
        list1.add(2);
        list1.add(3);

        List<Integer> list2 = new ArrayList<>();
        list2.add(2);
        list2.add(3);
        list2.add(4);

        List<Integer> intersection = new ArrayList<>();
        for (Integer item : list1) {
            if (list2.contains(item)) {
                intersection.add(item);
            }
        }

        System.out.println(intersection); // 输出: [2, 3]
    }
}

总结

  • retainAll 方法是最直接的方式,但会修改原始集合。
  • Stream API 提供了更灵活和函数式的编程方式,且不会修改原始集合。
  • 手动遍历适用于需要自定义逻辑的场景,但代码量较多。

根据具体需求选择合适的方法即可。


http://www.kler.cn/a/511765.html

相关文章:

  • 【计算机体系结构、微架构性能分析】core 与 uncore 分别是哪一些部分?区分 core 和 uncore
  • Python数据分析案例70——基于神经网络的时间序列预测(滞后性的效果,预测中存在的问题)
  • opencv笔记2
  • 解决 Error: Invalid or corrupt jarfile day04_studentManager.jar 报错问题
  • 芯片详细讲解,从而区分CPU、MPU、DSP、GPU、FPGA、MCU、SOC、ECU
  • ARM学习(42)CortexM3/M4 MPU配置
  • MECD+: 视频推理中事件级因果图推理--VLM长视频因果推理
  • Windows11电脑总是一闪一闪的,黑一下亮一些怎么解决
  • node.js 文件操作
  • 解决MAC安装软件时提示“xxx.app 显示已损坏”的方法
  • 抽奖系统(4——活动模块)
  • 网页固件升级界面设计
  • 【Maven】resources-plugin
  • vue3-sfc-loader 加载远程.vue文件(sfc)案例
  • React总结
  • 合合信息DocFlow产品解析与体验:人人可搭建的AI自动化单据处理工作流
  • UE虚幻引擎No Google Play Store Key:No OBB found报错如何处理?
  • 【spring boot统一功能处理】拦截器
  • 梯度提升决策树树(GBDT)公式推导
  • 【面试题】JVM部分[2025/1/13 ~ 2025/1/19]
  • pytest+playwright落地实战大纲
  • leetcode242-有效字母异位词
  • RoCE网络及其协议栈详解(没有中间商赚差价的网络)
  • 快速排序练习
  • Linux:生产者消费者模型
  • 第 3 章 核心处理层(上)