两个对象List根据属性取交集和差集及并集- 通用plus版

java8利用Stream方法求两个List对象的交集、差集与并集(即:anyMatch和allMatch和noneMatch的区别详解) 这里anyMatch表示,判断的条件里,任意一个元素符合条件,就返回true值。在allMatch 接口定义中是接收 Predicate 类型参数,在Lamdba表达式中 Predicate 是接收一个T类型参数,然后经过逻辑验证返回布尔值结果。判断数据列表中全部元素都不符合设置的predicate条件,如果是就返回true,否则返回false,流为空时总是返回true。判断数据列表中全部元素都符合设置的predicate条件,如果是就返回true,否则返回false,流为空时总是返回true。 阅读详情

背景

码哥很早之前基于工作需要, 写了个List对象的交、并、补的求解方法(两个对象List根据属性取交集和差集),发现很多小伙伴都有类似的需求, 刚好最近码哥有空了,就着手把之前的简陋方法封装下, 让它更通用些~

闲话少说, 直接上代码

public final class ListCompareUtil {
    private static final String ERROR_MESSAGE = "输入列表或比较条件不能为null";

    private ListCompareUtil() {
        throw new IllegalStateException("ListCompareUtil类不可实例化");
    }

    /**
     * 比较两个列表,返回在新列表中而不在现有列表中的元素
     *
     * @param <T>          列表元素的类型
     * @param newList      新列表
     * @param existingList 现有列表
     * @param condition    用于比较列表元素的条件
     * @return 在新列表中而不在现有列表中的元素列表
     */
    public static <T> List<T> getDifferenceList(List<T> newList, List<T> existingList, BiPredicate<T, T> condition) {
        if (newList == null || existingList == null || condition == null) {
            throw new IllegalArgumentException(ERROR_MESSAGE);
        }

        List<T> resultList = newList.stream()
                .filter(item -> existingList.stream().noneMatch(existingItem -> condition.test(item, existingItem)))
                .collect(Collectors.toList());

        // 返回一个不可修改的列表,防止外部修改结果列表
        return Collections.unmodifiableList(resultList);
    }

    /**
     * 求两个列表的并集
     *
     * @param <T>          列表元素的类型
     * @param newList      新列表
     * @param existingList 现有列表
     * @param condition    用于比较列表元素的条件
     * @return 两个列表的并集
     */
    public static <T> List<T> getUnionList(List<T> newList, List<T> existingList, BiPredicate<T, T> condition) {
        if (newList == null || existingList == null || condition == null) {
            throw new IllegalArgumentException(ERROR_MESSAGE);
        }

        List<T> resultList = new ArrayList<>(newList);
        existingList.forEach(existingItem -> {
            if (newList.stream().noneMatch(newItem -> condition.test(newItem, existingItem))) {
                resultList.add(existingItem);
            }
        });

        // 返回一个不可修改的列表,防止外部修改结果列表
        return Collections.unmodifiableList(resultList);
    }

    /**
     * 求两个列表的交集
     *
     * @param <T>          列表元素的类型
     * @param newList      新列表
     * @param existingList 现有列表
     * @param condition    用于比较列表元素的条件
     * @return 两个列表的交集
     */
    public static <T> List<T> getIntersectionList(List<T> newList, List<T> existingList, BiPredicate<T, T> condition) {
        if (newList == null || existingList == null || condition == null) {
            throw new IllegalArgumentException(ERROR_MESSAGE);
        }

        List<T> resultList = newList.stream()
                .filter(item -> existingList.stream().anyMatch(existingItem -> condition.test(item, existingItem)))
                .collect(Collectors.toList());

        // 返回一个不可修改的列表,防止外部修改结果列表
        return Collections.unmodifiableList(resultList);
    }
}

简单的使用方式示例

@Test
    public void getIntersectionList() {
        List<String> existList = Arrays.asList("apple", "banana", "orange", "grape");
        List<String> newList = Arrays.asList("apple", "grape", "mango");

        List<String> diffResult = ListCompareUtil.getIntersectionList(newList, existList, String::equals);
        System.out.println(diffResult);
    }

    @Test
    public void getUnionList() {
        List<String> existList = Arrays.asList("apple", "banana", "orange", "grape");
        List<String> newList = Arrays.asList("apple", "grape", "mango");

        List<String> diffResult = ListCompareUtil.getUnionList(newList, existList, String::equals);
        System.out.println(diffResult);
    }

    @Test
    public void getDifferenceList() {
        List<String> existList = Arrays.asList("apple", "banana", "orange", "grape");
        List<String> newList = Arrays.asList("apple", "grape", "mango");

        List<String> diffResult = ListCompareUtil.getDifferenceList(newList, existList, String::equals);
        System.out.println(diffResult);
    }

比对方式可自己定义, 比如多个属性的比对, 老规矩, 给需要的伙伴一个简单的示例, 自行调整

@Test
    public void test(){
        List<Person> newList = Arrays.asList(
                new Person("Alice", 25),
                new Person("Bob", 30),
                new Person("Charlie", 22)
        );

        List<Person> existingList = Arrays.asList(
                new Person("Alice", 25),
                new Person("David", 28)
        );

        BiPredicate<Person, Person> condition = (user1, user2) ->
                user1.getName().equals(user2.getName()) && user1.getAge() == user2.getAge();

        List<Person> differenceList = ListCompareUtil.getDifferenceList(newList, existingList, condition);
        List<Person> unionList = ListCompareUtil.getUnionList(newList, existingList, condition);
        List<Person> intersectionList = ListCompareUtil.getIntersectionList(newList, existingList, condition);

        System.out.println("Difference List:");
        differenceList.forEach(user -> System.out.println(user.getName() + " " + user.getAge()));

        System.out.println("Union List:");
        unionList.forEach(user -> System.out.println(user.getName() + " " + user.getAge()));

        System.out.println("Intersection List:");
        intersectionList.forEach(user -> System.out.println(user.getName() + " " + user.getAge()));
    }

感谢

不知不觉粉丝过5000了, 感谢大家关注~

如果你觉得有用, 记得三连, 不得不说, 有反馈时更新的会更勤快~

在这里插入图片描述

项目中的基础知识 yml中mytesthttps使用${添加链接描述添加链接描述​httpshttpshttpshttpshttps。 阅读详情

相关推荐

c++基本内容

【代码】c++基本内容。

qq_63068482的博客 253

两个不同对象的list集合,根据两个对象的共有属性取交集和并集

两个不同的list集合取交集和并集

weixin_43949112的博客 1729

Edge主页被2345劫持?手动清理注册表与组策略的完整方案

浏览器主页劫持是Windows系统中常见的恶意篡改行为,其原理是通过修改注册表、快捷方式、组策略等多处系统配置,强制锁定浏览器启动页。这类劫持不仅影响上网体验,还可能带来隐私泄露和恶意软件感染风险。在安全防护与系统优化场景中,掌握手动清理主页劫持的技能至关重要。本文针对Edge主页被2345导航劫持的问题,深入解析劫持入口,提供从快捷方式、注册表到组策略的逐层清理步骤,并给出防复发策略,帮助用户彻底摆脱顽固劫持。

weixin_30582943的博客 380

两个存对象的List,求并集

比较对象的某几个字段,相等则表示对象相等,求并集: 将对象的那几个字段拼成一个String存于map中作为key, 对象作为value,代码如下: /******对象定义********/ Class Obj{ int attr1; String attr2; String attr3; String attr4; @getter//有get与set方法 @s...

zhif的博客 2961

2025年最新Cesium学习示例:Cesium-Examples

2025年最新Cesium学习示例:Cesium-Examples

2403_88103571的博客 1008

Unity AssetBundle 之 (入门)简单的资源打包成AB包的方法

Unity AssetBundle 之 (入门)简单的资源打包成AB包的方法 目录 Unity AssetBundle 之 (入门)简单的资源打包成AB包的方法 一、简单介绍 二、实现原理 三、注意事项 四、效果预览 五、实现步骤 六、关键代码 一、简单介绍 Unity中的一些基础知识点。 本节介绍,Asset Bundle 在 Unity中的使用,入门第一篇,如何AssetBundle标记,如何打包成AssetBundle的操作方法,有不对的地方欢迎指正。...

仙魁XAN 1万+

Java List 集合取 交集、并集、差集、补集 Java集合取交集、Java集合并集

1、在日常开发中,经常会遇到对2个集合的操作,例如2个集合之间取相同的元素(交集),2个集合之间取不相同的元素(差集)等等。。。2、本文系统性的整理,Java中集合。

HaHa_Sir的博客 6万+

Java黑皮书课后题第5章:*5.9(找出得最高分的前两个学生)编写程序,提示用户输入学生的个数、每个学生名字及分数,最后显示获得最高分的学生

*5.9(找出得最高分的前两个学生)编写程序,提示用户输入学生的个数、每个学生名字及分数,最后显示获得最高分的学生名字、次高分的学生名字题目题目概述next()读取一个字符与nextLine()读取一行破题代码 题目 题目概述 *5.9(找出得最高分的前两个学生)编写程序,提示用户输入学生的个数、每个学生名字及分数,最后显示获得最高分的学生名字、次高分的学生名字 使用Scanner类的next()方法而不是nextLine()方法来读取名字 next()读取一个字符与nextLine()读取一行 举个例子理

weixin_46356698的博客 2154

mybatis-plus常用的方法

mybatisplus常见用法

sainazuoan1的博客 321

基于光电传感的非接触式酒精浓度检测系统设计与实现

本文详细介绍了基于光电传感技术的非接触式酒精浓度检测系统设计与实现。系统利用940nm红外LED和OPT101光电传感器,结合朗伯-比尔定律,通过STM32微控制器进行信号采集与处理,实现了快速、准确的酒精浓度测量,测量精度达±1%,适用于工业检测和便携式应用场景。

y7z8a的博客 363

Android13 AudioFlinger混音流程全解析:从prepareTracks_l到threadLoop_write的底层实现

本文深入解析Android13 AudioFlinger混音流程,从prepareTracks_l到threadLoop_write的底层实现。详细剖析MixerThread的核心工作循环,包括音轨预处理、混音算法执行及硬件写入机制,帮助开发者优化音频性能并处理多音轨场景。

tea88的博客 1130

C++函数对象

如果一个类中实现了重载括号()运算符,即operator(),那么这个类的对象就是一个函数对象。因为函数对象实现了operator(),所以它就有了类似函数的行为,可以像函数一样来调用它,所以函数对象又称为仿函数: class CSquare { public: void operator()(int& x) { x = x * x; } }; int main() {...

milanleon的专栏 2503

ETAS工具导入Com Arxml修改步骤

通讯协议栈开发一般通过导入DBC实现,ETAS工具本身导入DBC也是生成arxml后执行cfggen,本文介绍直接导入客户提供的arxml文件,实现通讯协议栈的生成。通过Arxml导入相比于DBC来说,少了从DBC转为arxml的过程。而且arxml中能提供的信息也会更多。如果是DBC的话,很多信息(如PNC的映射,CANTP的配置等)都需要额外配置。不过还有连DBC都无法提供的,那就更麻烦了~

赞的博客 1541

【Redis】从零开始的 Redis 学习

本文主要讲解了 redis 的安装和基础使用,包括全局指令和常见数据类型,最后使用 c++ 自定义 redis 客户端连接和使用 redis 服务器。

x_p96484685433的博客 286

实战落地!Python抓取股票历史数据:开盘/收盘/成交量全维度爬取(附数据清洗+可视化)

股票历史数据抓取的核心是“数据准确性+完整性”,网页爬取适合小批量、个性化需求,API调用适合批量、标准化需求。多市场数据抓取:适配港股(00700.HK)、美股(AAPL)的抓取逻辑;高频数据抓取:抓取分钟级、小时级行情数据,用于短线量化策略;财务数据扩展:抓取市盈率、市净率、净利润等财务指标,结合价格数据做基本面分析;量化策略回测:将清洗后的数据接入Backtrader、VNPY等量化框架,验证策略有效性。

专注于Python爬虫开发,分享爬虫技巧、项目实战与反爬经验,使用Scrapy、BeautifulSoup等工具,解决数据抓取难题。 1739

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

C++提高编程(三)

本阶段主要针对C++泛型编程和STL技术做详细讲解,探讨C++更深层的使用

qq_46518480的博客 1589

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

阶段3/3:C++提高编程讲义

C++模板编程的核心概念和应用。重点内容包括: 函数模板的基本语法和使用方法,通过template<typename T>声明模板,支持自动类型推导和显式指定类型两种调用方式 函数模板的注意事项:类型推导必须一致、必须确定具体类型才能使用 通过选择排序案例展示了函数模板的实际应用 对比普通函数与函数模板的区别,特别是在隐式类型转换方面的差异 函数模板的调用规则和重载特性 模板的局限性,如无法直接处理数组等特殊类型 文章通过具体代码示例演示了模板在提高代码复用性方面的优势......

2201_75888254的博客 404

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

Roaring Bitmap:亿级用户标签系统的高效存储与查询实战

在用户画像、精准营销等大数据场景下,高效处理海量用户标签集合的交并差运算是核心技术挑战。传统数据库方案在应对此类集合运算时,常面临查询缓慢和内存占用巨大的瓶颈。位图索引作为一种高效的数据结构,通过二进制位表示集合成员关系,能实现O(1)复杂度的集合运算,但其在稀疏数据场景下存在严重的内存浪费。Roaring Bitmap通过创新的分桶压缩机制,将整数范围划分为多个容器,并自适应地采用数组、位图和游程三种存储格式,在保持位图高速运算优势的同时,大幅优化了稀疏数据的存储空间。这种技术方案为亿级用户标签管理、实时

weixin_30470643的博客 384

python核心语法

【代码】python核心语法。

2301_81507539的博客 199

SpringBoot项目必备工具类库盘点:从Hutool到MapStruct的实战选型指南

在Java后端开发中,工具类库的选择直接影响代码质量与开发效率。无论是集合判空、字符串处理,还是对象拷贝、Excel解析,成熟的开源工具都能帮助我们避免重复造轮子,同时降低踩坑概率。Guava提供强大的不可变集合与缓存机制,Apache Commons以稳定的字符串和集合操作见长,而国产利器Hutool则凭借覆盖全面的API和中文文档成为日常开发的首选。在对象转换场景下,Lombok简化样板代码,MapStruct通过编译期代码生成实现高性能映射,显著优于传统反射方案。针对大数据量导入导出,EasyExce

weixin_34008784的博客 408

C++提高编程

学习目标:vector中存放自定义数据类型,并打印输出//自定义数据类型public:mAge = age;//存放对象//创建数据it!= v.end();it++) {//放对象指针//创建数据it!= v.end();test02();return 0;

丰锋的博客 351

蓝桥杯webJS

filter是数组自带方法遍历数组,筛选出满足条件的元素,组成新数组返回不会修改原数组!语法:js运行const 新数组 = 原数组.filter( (item, index) => {// 返回 true → 保留这个元素// 返回 false → 剔除这个元素})

2501_93485775的博客 171

Java基础面试题总结《九》

选择 16384 是为了将集群状态同步的网络开销控制在 2KB 左右,同时又能支持上千个节点的集群规模,是工程实践中的最优解。默认使用#{}:它是安全的、高性能的,能覆盖 95% 以上的参数传递需求。谨慎使用${}:仅在动态表名、列名等无法使用预编译的场景下使用,且必须做好参数校验。面试加分点:能说出#{}底层是${}底层是字符串拼接,并能结合 SQL 注入原理进行解释。@Mapper:适合小型项目或者只有少量 Mapper 接口的场景,或者作为的补充(例如某些特殊接口不在扫描路径下)。

qq_55862497的博客 218

基于Alibaba-Graph构建企业级AI Agent工作流:以HR招聘智能体为例

在软件工程领域,工作流引擎是协调复杂业务流程、实现任务自动化编排的核心技术。其原理通常基于有向无环图(DAG)模型,将业务逻辑分解为独立的节点(任务单元),并通过边定义节点间的依赖关系与数据流向。这种架构的技术价值在于实现了业务逻辑的可视化、解耦与高效调度,尤其适用于需要多步骤、有条件分支和并行处理的场景。在人工智能工程化实践中,工作流引擎成为调度多个AI智能体(Agent)协同作业的理想框架。每个智能体可被视为一个具备特定能力的节点,例如简历解析、技能匹配或决策生成。通过工作流引擎进行编排,可以解决智能体

weixin_34032621的博客 390

PyFlink Table API 表达式(Expressions)完整指南:从 col/lit 基础算子到 JSON 与时间处理

本文是一份面向 PyFlink Table API 开发者的表达式(Expression)编程指南。它围绕 [flink-python/docs/reference/pyflink.table/expressions.rst](https://link.gitcode.com/i/85290ed7350825f46a75319e06d00f1f) 定义的 API 全景展开,系统梳理 `pyflin

gitblog_00718的博客 439

Ceph libfdb 实战指南:用 C++ 在 FoundationDB 上构建键值、事务与查询应用

libfdb 是 Ceph 仓库中([src/rgw/fdb/](https://link.gitcode.com/i/4d563ac5e05af75043e6be71e46b9a80))为 FoundationDB C API 编写的一层现代化 C++ 绑定库,它把 FoundationDB 的键值存储、可重放事务、键选择器(key selector)、区间查询代数、内容键(content ke

gitblog_00923的博客 750
上一篇: 小白的GPT入门指南 - 工具篇
码哥说
博客等级 码龄8年 5645粉丝 172原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

码哥说

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值