导读:本期聚焦于小伙伴创作的《Java中如何快速判断两个集合是否有交集_集合交集判断方法》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《Java中如何快速判断两个集合是否有交集_集合交集判断方法》有用,将其分享出去将是对创作者最好的鼓励。

在Java开发中,判断两个集合是否存在交集是高频需求,比如校验两个用户组的权限是否有重叠、判断两个商品标签是否有共同项等场景都需要用到这个能力。不同的实现方式在代码简洁度和性能上有所差异,开发者可以根据实际场景选择。

Java中如何快速判断两个集合是否有交集_集合交集判断方法

方法一:使用Collection的retainAll方法

Java的Collection接口提供了retainAll方法,该方法的作用是保留集合中存在于指定集合里的元素,也就是求两个集合的交集。我们可以通过判断调用该方法后集合是否发生变化,来间接判断两个集合是否有交集。

实现逻辑是:先拷贝一个原集合的副本,然后调用副本的retainAll方法传入另一个集合,如果副本的元素数量发生了变化,说明两个集合存在交集。

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

public class CollectionIntersectionDemo {
    public static void main(String[] args) {
        // 定义第一个集合
        List<String> list1 = new ArrayList<>();
        list1.add("apple");
        list1.add("banana");
        list1.add("orange");

        // 定义第二个集合
        List<String> list2 = new ArrayList<>();
        list2.add("banana");
        list2.add("grape");
        list2.add("pear");

        // 判断两个集合是否有交集
        boolean hasIntersection = hasIntersectionByRetainAll(list1, list2);
        System.out.println("两个集合是否有交集:" + hasIntersection);
    }

    /**
     * 使用retainAll方法判断两个集合是否有交集
     * @param coll1 第一个集合
     * @param coll2 第二个集合
     * @return 有交集返回true,否则返回false
     */
    private static boolean hasIntersectionByRetainAll(Collection<?> coll1, Collection<?> coll2) {
        // 拷贝第一个集合,避免修改原集合
        Collection<?> tempColl = new ArrayList<>(coll1);
        // 求交集,返回值是集合是否发生了改变
        boolean changed = tempColl.retainAll(coll2);
        // 如果集合发生了改变,说明存在交集
        return changed;
    }
}

这种方式的优点是代码简洁,不需要自己写遍历逻辑,但是retainAll方法会修改拷贝的集合,不过因为我们提前做了拷贝,所以不会影响原集合。需要注意的是,如果集合元素较多,拷贝集合会有一定的内存开销。

方法二:使用循环遍历判断

如果不想使用retainAll方法,也可以通过循环遍历其中一个集合的元素,判断是否存在于另一个集合中,只要找到一个共同元素就可以返回结果,不需要遍历完所有元素。

为了提升查询效率,建议把元素较多的集合转成HashSet,这样查询元素的时间复杂度是O(1),整体时间复杂度是O(n),n是较小集合的元素数量。

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

public class LoopIntersectionDemo {
    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(3);
        list2.add(4);
        list2.add(5);

        boolean hasIntersection = hasIntersectionByLoop(list1, list2);
        System.out.println("两个集合是否有交集:" + hasIntersection);
    }

    /**
     * 使用循环遍历判断两个集合是否有交集
     * @param coll1 第一个集合
     * @param coll2 第二个集合
     * @return 有交集返回true,否则返回false
     */
    private static boolean hasIntersectionByLoop(Collection<?> coll1, Collection<?> coll2) {
        // 处理空集合的情况
        if (coll1 == null || coll2 == null || coll1.isEmpty() || coll2.isEmpty()) {
            return false;
        }
        // 把元素较多的集合转成HashSet,提升查询效率
        Collection<?> smallerColl = coll1.size() <= coll2.size() ? coll1 : coll2;
        Collection<?> largerColl = coll1.size() <= coll2.size() ? coll2 : coll1;
        Set<Object> tempSet = new HashSet<>(largerColl);
        // 遍历较小集合的元素,判断是否存在于较大集合中
        for (Object item : smallerColl) {
            if (tempSet.contains(item)) {
                return true;
            }
        }
        return false;
    }
}

这种方式的灵活性更高,而且不需要修改原集合,也不需要拷贝整个集合做交集运算,在元素数量较多的时候性能表现更好,尤其是当两个集合大小差异较大的时候,优势更明显。

方法三:使用Apache Commons Collections工具类

如果项目中已经引入了Apache Commons Collections依赖,可以直接使用工具类提供的CollectionUtils.containsAny方法,该方法可以直接判断两个集合是否有交集,内部实现也是基于循环遍历的逻辑,但是封装得更加完善,还处理了null值的情况。

首先需要引入对应的依赖,如果是Maven项目,可以在pom.xml中添加如下配置:

<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-collections4</artifactId>
    <version>4.4</version>
</dependency>

使用示例代码如下:

import org.apache.commons.collections4.CollectionUtils;
import java.util.Arrays;
import java.util.List;

public class CommonsIntersectionDemo {
    public static void main(String[] args) {
        List<String> list1 = Arrays.asList("a", "b", "c");
        List<String> list2 = Arrays.asList("c", "d", "e");

        // 直接调用工具类方法判断是否有交集
        boolean hasIntersection = CollectionUtils.containsAny(list1, list2);
        System.out.println("两个集合是否有交集:" + hasIntersection);
    }
}

这种方式的代码最简洁,适合已经引入相关依赖的项目,但是如果没有相关依赖,为了这个功能单独引入会增加项目的依赖体积,需要权衡是否使用。

不同方法的对比

我们可以通过下面的表格对比三种方法的优缺点和适用场景:

方法优点缺点适用场景
retainAll方法代码简洁,无需自己实现遍历逻辑需要拷贝集合,有内存开销,会修改拷贝的集合集合元素较少,追求代码简洁的场景
循环遍历性能较好,无需额外依赖,不修改原集合需要自己实现逻辑,代码量稍多集合元素较多,对性能要求高的场景
Apache Commons工具类代码最简洁,处理了边界情况需要额外引入依赖项目已经引入相关依赖的场景

注意事项

  • 判断交集前需要先处理集合为null或者空集合的情况,避免出现空指针异常。
  • 如果集合中的元素是自定义对象,需要确保对象正确重写了equalshashCode方法,否则判断元素是否存在的时候会出现不符合预期的结果。
  • 如果集合是有序的,比如TreeSet,可以利用有序的特性做更高效的判断,比如双指针遍历,但是实现逻辑会更复杂,一般场景不需要这么做。

Java集合交集判断CollectionretainAll修改时间:2026-07-20 14:30:39

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。