Java求两个 List集合的交集元素的多种实现方式

 更新时间:2025年05月21日 10:05:38   作者:冰糖心书房  
在 Java 中,求两个 List 的交集元素可以通过多种方式实现,常见的做法包括使用 retainAll 方法、Stream API 或手动遍历,以下是这些方法的原理和实现,需要的朋友可以参考下

1. 使用 retainAll 方法

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

原理:

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

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

方法定义

boolean retainAll(Collection<?> c);

参数:

  • c:包含需要保留元素的集合。

返回值:

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

方法行为

  • 保留交集retainAll 方法会保留当前列表与指定集合的交集。
  • 移除其他元素:当前列表中不在指定集合中的元素会被移除。
  • 修改原列表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 方法来比较元素是否相同。
    • 如果集合中包含自定义对象,请确保正确重写了 equals 和 hashCode 方法。
  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 提供了更灵活和函数式的编程方式,且不会修改原始集合。
  • 手动遍历适用于需要自定义逻辑的场景,但代码量较多。

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

到此这篇关于Java求两个 List集合的交集元素的多种实现方式的文章就介绍到这了,更多相关Java两个 List集合交集元素内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Hibernate缓存机制实例代码解析

    Hibernate缓存机制实例代码解析

    这篇文章主要介绍了Hibernate缓存机制实例代码解析,介绍了查询缓存,一级二级缓存等内容,分享了相关代码示例,小编觉得还是挺不错的,具有一定借鉴价值,需要的朋友可以参考下
    2018-02-02
  • 如何使用@AllArgsConstructor和final 代替 @Autowired

    如何使用@AllArgsConstructor和final 代替 @Autowired

    这篇文章主要介绍了使用@AllArgsConstructor和final 代替 @Autowired方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-09-09
  • Spring框架花式创建Bean的n种方法(小结)

    Spring框架花式创建Bean的n种方法(小结)

    这篇文章主要介绍了Spring框架花式创建Bean的n种方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-03-03
  • Easycode自动化springboot的curd

    Easycode自动化springboot的curd

    这篇文章主要介绍了Easycode自动化springboot的curd,围绕主题的相关资料展开详细内容,具有一定的参考价值,需要的小伙伴可以参考一下,希望给对你有所帮助
    2022-01-01
  • 关于Mybatis-Plus Update更新策略问题

    关于Mybatis-Plus Update更新策略问题

    这篇文章主要介绍了关于Mybatis-Plus Update更新策略问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-11-11
  • 分析Java中为什么String不可变

    分析Java中为什么String不可变

    Java中为什么String是不可变性的。今天我们从多角度解析为什么Java把String做成不可变的。
    2021-06-06
  • java Map转Object与Object转Map实现代码

    java Map转Object与Object转Map实现代码

    这篇文章主要介绍了 java Map转Object与Object转Map实现代码的相关资料,需要的朋友可以参考下
    2017-02-02
  • Java中csv文件读写超详细分析

    Java中csv文件读写超详细分析

    CSV是一种通用的、相对简单的文件格式,其文件以纯文本形式存储表格数据,下面这篇文章主要给大家介绍了关于Java中csv文件读写分析的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2023-05-05
  • SpringBoot之HandlerInterceptor拦截器的使用详解

    SpringBoot之HandlerInterceptor拦截器的使用详解

    这篇文章主要介绍了SpringBoot之HandlerInterceptor拦截器的使用详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-10-10
  • Java前后端分离项目跨域问题解决方案

    Java前后端分离项目跨域问题解决方案

    本文主要介绍了Java前后端分离项目跨域问题解决方案,其中后端基于SpringBoot,前端使用了jQuery、axios等框架,具有一定的参考价值,感兴趣的可以了解一下
    2024-03-03

最新评论