java两个List的交集,并集方式

2025-03-06 17:50

本文主要是介绍java两个List的交集,并集方式,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

《java两个List的交集,并集方式》文章主要介绍了Java中两个List的交集和并集的处理方法,推荐使用Apache的CollectionUtils工具类,因为它简单且不会改变原有集合,同时,文章...

java两个List的交集,并集

方法一

  • 使用apache的CollectionUtils工具类(推荐)
public static void main(String[] args) {

    String[] arrayA = new String[] { "1", "2", "3", "4"};
    String[] arrayB = new String[] { "3", "4", "5", "6" };
    List<String> listA = Arrays.asList(arrayA);
    List<String> listB = Arrays.asList(arrayB);

    //1、并集 union
    System.out.println(CollectionUtils.union(listA, listB));
China编程    //输出: [1, 2, 3, 4, 5, 6]

    //2、交集 intersection
    System.out.println(CollectionUtils.intersection(listA, listB));
    //输出:[3, 4]

    //3、交集的补集(析取)disjunction
    System.out.println(CollectionUtils.disjunction(listA, listB));
    //输出:[1, 2, 5, 6]

    //4、差集(扣除)
    System.out.println(CollectionUtils.subtract(listA, listB));
    //输出:[1, 2]
}

方法二

  • List自带方法
public static void main(String[] args) {

    String[] arrayA = new String[] { "1", "2", "3", "4"};
    String[] arrayB = new String[] { "3", "4", "5", "6" };
    List<String> listA = Arrays.asList(arrayA);
    List<String> listB = Arrays.asList(arrayB);

    //1、交集
    List<String>  jiaoList = new ArrayList<>(listA);
    jiaoList.retainAll(listB);
    System.out.println(jiaoList);编程
    //输出:[3, 4]

    //2、差集
    List<String>  chaList = new ArrayList<>(listA);
    chaList.removeAll(listB);
    System.out.println(chaList);
    //输出:[1, 2]

    //3、并集 (先做差集再做添加所有)
    List<String>  bingList = new ArrayList<>(listA);
    bingList.removeAll(listB); // bingList为 [1, 2]
    bingList.addAll(listB);  //添加[3,4,5,6]
    System.out.println(bingList);
    //输出:[1, 2, 3, 4, 编程5, 6]
}

注意 : intersection和retainAll的差别

要注意的是它们的返回类型是不一样的,intersection返回的是一个新的List集合,而retainAll返回是Bollean类型那就说明retainAll方法是对原有集合进行处理再返回原有集合,会改变原有集合中的内容。

个人观点:

1、从性能角度来考虑的话,List自带会高点,因为它不用再创建新的集合。

2、需要注意的是:因为retainAll因为会改变原有集合,所以该集合需要多次使用就不适合用retainAll。

注意:

Arrays.asList将数组转集合不能进行add和remove操作。

原因:

调用Arrays.asList()生产的List的add、remove方法时报异常,这是由Arrays.asList() 返回的市Arrays的内部类ArrayList, 而不是java.util.ArrayList。

Arrays的内部类ArrayList和java.util.ArrayList都是继承AbstractList,remove、add等方法AbstractList中是默认throw UnsupportedOperationException而且不作任何操作。

java.util.ArrayList重新了这些方法而Arrays的内部类ArrayList没有重新,所以会抛出异常。

  • 所以正确做法如下
String[] array = {"1","2","3","4","5"};
List<String> list = Arrays.asList(array);
List arrList = new ArrayList(list);
arrList.add("6");

方法三

JDK1.8 stream 新特性

String[] arrayA = new String[] { "1", "2", "3", "4"};
    String[] arrayB = new String[] { "3", "4", "5", "6" };
    List<String> listA = Arrays.asList(arrayA);
    List<String> listB =php Arrays.asList(arrayB);

    // 交集
    List<String> intersection = listA.stream().filter(item -> listB.contains(item)).collect(toList());
    System.out.println(intersection);
    //输出:[3, 4]

    // 差集 (list1 - list2)
    List<String> reduceList = listA.stream().filter(item -> !listB.contains(item)).collect(toList());
    System.out.println(reduceList);
    //输出:[1, 2]

    // 并集 (新建集合:1、是因为不影响原始集合。2、Arrays.asList不能aAjLMgFuQMddd和remove操作。
    List<String> listAll = listA.parallelStream().collect(toList());
    List<String> listAll2 = listB.parallelStream().collect(toList());
    listAll.addAll(listAll2);
    System.out.println(listAll);
    //输出:[1, 2, 3, 4, 3, 4, 5, 6]

    // 去重并集
    List<String> list =new ArrayList<>(listA);
    list.addAll(listB);
    List<String> listAllDistinct = list.stream().distinct().collect(toList());
    System.out.println(listAllDistinct);
    //输出:[1, 2, 3, 4, 5, 6]

总结 : 这三种推荐第一种方式,因为第二种还需要确定该集合是否被多次调用。第三种可读性不高。

对象集合交、并、差处理

因为对象的equels比较是比较两个对象的内存地址,所以除非是同一对象,否则equel返回永远是false。

但我们实际开发中 在我们的业务系统中判断对象时有时候需要的不是一种严格意义上的相等,而是一种业务上的对象相等。在这种情况下,原生的equals方法就不能满足我们的需求了,所以这个时候我们需要重写equals方法。

说明 :String为什么可以使用equels方法为什么只要字符串相等就为true,那是因为String类重写了equal和hashCode方法,比较的是值。

public class Person {
    private String name;
    private Integer age;
    public Person(String name, Integer age) {
        this.name = name;
        this.age = age;
    }
    /**
     * 为什么重写equals方法一定要重写hashCode方法下面也会讲
     */
    @Override
    public int hashCode() {
        String result = name + age;
        return result.hashCode();
    }
    /**
     * 重写 equals 方法 根据name和age都相同那么对象就默认相同
     */
    @Override
    public boolean equals(Object obj) {
        Person u = (Person) obj;
        return this.getName().equals(u.getName()) && (this.age.equals(u.getAge()));
    }
    /**
     * 重写 toString 方法
     */
    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
  }

这里根据name和age都相同那么就默认相同对象。

public static void main(String[] args) {

        List<Person> personList = Lists.newArrayList();
        Person person1 = new Person("小小",3);
        Person person2 = new Person("中中",4);
        personList.add(person1);
        personList.add(person2);

        List<Person> person1List = Lists.newArrayList();
        Person person3 = new Person("中中",4);
        Person person4 = new Person("大大",5);
        person1List.add(person3);
        person1List.add(person4);
        /**
         * 1、差集
         */
        System.out.println(CollectionUtils.subtract(personList, person1List));
        //输出:[Person{name='小小', age=3}]

        /**
         * 2、并集
         */
        System.out.println(CollectionUtils.union(personList, person1List));
        //输出:[Person{name='小小', age=3}, Person{name='中中', age=4}, Person{name='大大', age=5}]

        /**
         * 3、交集
         */
        System.out.println(CollectionUtils.intersection(personList, person1List));
        //输出:[Person{name='中中', age=4}]

        /**
         * 4、交集的补集(析取)
         */
        System.out.println(CollectionUtils.disjunction(personList, person1List));
        //输出:[Person{name='小小', age=3}, Person{name='大大', age=5}]
    }

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程China编程(www.chinasem.cn)。

这篇关于java两个List的交集,并集方式的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1153661

相关文章

Spring AI集成DeepSeek三步搞定Java智能应用的详细过程

《SpringAI集成DeepSeek三步搞定Java智能应用的详细过程》本文介绍了如何使用SpringAI集成DeepSeek,一个国内顶尖的多模态大模型,SpringAI提供了一套统一的接口,简... 目录DeepSeek 介绍Spring AI 是什么?Spring AI 的主要功能包括1、环境准备2

Spring AI集成DeepSeek实现流式输出的操作方法

《SpringAI集成DeepSeek实现流式输出的操作方法》本文介绍了如何在SpringBoot中使用Sse(Server-SentEvents)技术实现流式输出,后端使用SpringMVC中的S... 目录一、后端代码二、前端代码三、运行项目小天有话说题外话参考资料前面一篇文章我们实现了《Spring

Python中如何控制小数点精度与对齐方式

《Python中如何控制小数点精度与对齐方式》在Python编程中,数据输出格式化是一个常见的需求,尤其是在涉及到小数点精度和对齐方式时,下面小编就来为大家介绍一下如何在Python中实现这些功能吧... 目录一、控制小数点精度1. 使用 round() 函数2. 使用字符串格式化二、控制对齐方式1. 使用

Spring AI与DeepSeek实战一之快速打造智能对话应用

《SpringAI与DeepSeek实战一之快速打造智能对话应用》本文详细介绍了如何通过SpringAI框架集成DeepSeek大模型,实现普通对话和流式对话功能,步骤包括申请API-KEY、项目搭... 目录一、概述二、申请DeepSeek的API-KEY三、项目搭建3.1. 开发环境要求3.2. mav

Springboot的自动配置是什么及注意事项

《Springboot的自动配置是什么及注意事项》SpringBoot的自动配置(Auto-configuration)是指框架根据项目的依赖和应用程序的环境自动配置Spring应用上下文中的Bean... 目录核心概念:自动配置的关键特点:自动配置工作原理:示例:需要注意的点1.默认配置可能不适合所有场景

Nginx配置系统服务&设置环境变量方式

《Nginx配置系统服务&设置环境变量方式》本文介绍了如何将Nginx配置为系统服务并设置环境变量,以便更方便地对Nginx进行操作,通过配置系统服务,可以使用系统命令来启动、停止或重新加载Nginx... 目录1.Nginx操作问题2.配置系统服android务3.设置环境变量总结1.Nginx操作问题

使用Apache POI在Java中实现Excel单元格的合并

《使用ApachePOI在Java中实现Excel单元格的合并》在日常工作中,Excel是一个不可或缺的工具,尤其是在处理大量数据时,本文将介绍如何使用ApachePOI库在Java中实现Excel... 目录工具类介绍工具类代码调用示例依赖配置总结在日常工作中,Excel 是一个不可或缺的工http://

Java8需要知道的4个函数式接口简单教程

《Java8需要知道的4个函数式接口简单教程》:本文主要介绍Java8中引入的函数式接口,包括Consumer、Supplier、Predicate和Function,以及它们的用法和特点,文中... 目录什么是函数是接口?Consumer接口定义核心特点注意事项常见用法1.基本用法2.结合andThen链

spring @EventListener 事件与监听的示例详解

《spring@EventListener事件与监听的示例详解》本文介绍了自定义Spring事件和监听器的方法,包括如何发布事件、监听事件以及如何处理异步事件,通过示例代码和日志,展示了事件的顺序... 目录1、自定义Application Event2、自定义监听3、测试4、源代码5、其他5.1 顺序执行

SpringBoot实现导出复杂对象到Excel文件

《SpringBoot实现导出复杂对象到Excel文件》这篇文章主要为大家详细介绍了如何使用Hutool和EasyExcel两种方式来实现在SpringBoot项目中导出复杂对象到Excel文件,需要... 在Spring Boot项目中导出复杂对象到Excel文件,可以利用Hutool或EasyExcel