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

devtools/2025/1/21 9:48:20/

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

1. 使用 retainAll 方法

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

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

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


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

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

示例代码

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

java">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); // trueSystem.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 会保留列表中的重复元素。
    • 例如:
      java">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 中。
示例代码:
java">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 中。
  • 如果存在,则将其添加到结果集合中。
示例代码:
java">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.ppmy.cn/devtools/152313.html

相关文章

基于LoRA微调的预训练大模型在离线RL量化交易中自动学习专家决策,达成47.98%累计收益

“Pretrained LLM Adapted with LoRA as a Decision Transformer for Offline RL in Quantitative Trading” 论文地址&#xff1a;https://arxiv.org/pdf/2411.17900 Github地址&#xff1a;https://github.com/syyunn/finrl-dt 摘要 开发量化交易策略时采用强化学习颇具挑战…

协作机器人公司切入人形机器人赛道,大有可为!

2025年1月13日&#xff0c;德国知名AI机器人、人形机器人公司【Neura Robotics】宣布完成1.2亿欧元融资&#xff08;约合9.3亿元人民币&#xff09;&#xff0c;这家最早涉足人形机机器人并推出双足人形产品的协作机器人厂家再一次进入大众视野。 据官方介绍本轮融资由意大利阿…

C++ List 容器:实现原理深度解析

1.基本结构 1.1list底层 list底层是一个双向链表&#xff0c;每个节点包含三个主要部分&#xff1a;存储的数据&#xff0c;指向前一个节点和后一个节点的指针。我们首先定义一个 list_node 结构体来描述链表节点。 template <class T> struct list_node {T _data;lis…

半导体、芯片、人工智能、智能驾驶汽车的趋势

1. 市场增长与需求 汽车半导体市场&#xff1a;预计到2025年&#xff0c;中国汽车半导体市场仍将保持稳健增长态势&#xff0c;AI和能源将成为未来最重要的两大变革因素。2023年中国汽车电子芯片行业市场规模约为820.8亿元&#xff0c;预计2024年有望增至905.4亿元左右。随着新…

PyTorch使用教程(13)-一文搞定模型的可视化和训练过程监控

一、简介 在现代深度学习的研究和开发中&#xff0c;模型的可视化和监控是不可或缺的一部分。PyTorch&#xff0c;作为一个流行的深度学习框架&#xff0c;通过其丰富的生态系统提供了多种工具来满足这一需求。其中&#xff0c;torch.utils.tensorboard 是一个强大的接口&…

http转化为https生成自签名证书

背景 项目开发阶段前后交互采用http协议&#xff0c;演示环境采用htttps协议 &#xff0c;此处为个人demo案例 组件 后端&#xff1a;springBoot 前端&#xff1a;vue web 服务&#xff1a;tomcat 部署环境&#xff1a;linux 生成自签名证书 创建目录 存储证书位置 # mkdir -p…

1.4走向不同:GPT 与 BERT 的选择——两大NLP模型的深度解析

走向不同:GPT 与 BERT 的选择——两大NLP模型的深度解析 在自然语言处理(NLP)领域,GPT(Generative Pretrained Transformer)和BERT(Bidirectional Encoder Representations from Transformers)无疑是最具代表性和影响力的两个模型。它们都基于 Transformer 架构,但在…

Python毕业设计选题:基于django+vue的二手电子设备交易平台设计与开发

开发语言&#xff1a;Python框架&#xff1a;djangoPython版本&#xff1a;python3.7.7数据库&#xff1a;mysql 5.7数据库工具&#xff1a;Navicat11开发软件&#xff1a;PyCharm 系统展示 管理员登录 管理员功能界面 用户管理 设备类型管理 设备信息管理 系统首页 设备信息…