List根据实体类中某一字段进行去重

List根据实体类中某一字段进行去重

1、使用 toMap 收集器

利用 Collectors.toMap 收集器将流中的元素映射为一个 Map,其中键为 OmsOrderId,值为元素本身。如果存在相同的键(即相同的 OmsOrderId),则使用 (existing, replacement) -> existing 函数来决定保留哪一个元素。最后,通过调用 values() 方法,获取 Map 中的值集合,即去重后的元素集合。

  • 利用了 Collectors.toMap 收集器,将元素映射到它们的 OmsOrderId,然后通过 values() 方法获取去重后的值。
  • 适用于你希望保留重复元素中的第一个元素的情况,它使用了 existing -> existing 的合并函数来解决重复键的问题。
java 复制代码
// 从 orderCompanyList 创建一个流,并进行以下操作:
List<StorageDeliveryPrintExcelResp> uniqueOrders = new ArrayList<>(orderCompanyList.stream()
        // 使用 Collectors.toMap 收集器将流中的元素映射为 Map,其中键为 OmsOrderId,值为元素本身。
        .collect(Collectors.toMap(
                StorageDeliveryPrintExcelResp::getOmsOrderId, // 使用 StorageDeliveryPrintExcelResp 对象的 getOmsOrderId 方法作为键
                Function.identity(), // 使用 Function.identity() 作为值,表示保留元素本身
                (existing, replacement) -> existing // 如果存在重复的键,则使用现有的元素替换重复元素,即保留第一个出现的元素
        ))
        // 获取 Map 中的值集合,即去重后的元素集合
        .values());

2、使用 collectingAndThen 收集器和 TreeSet

  • 将流中的元素收集到一个 TreeSet 中,该 TreeSet 按照 OmsOrderId 属性进行比较和排序,同时去除重复元素。
  • 使用 Collectors.collectingAndThen 收集器对 TreeSet 进行后续处理,将其转换为一个新的 ArrayList
java 复制代码
// 从 orderCompanyList 创建一个流,并进行以下操作:
List<StorageDeliveryPrintExcelResp> uniqueOrders2 = orderCompanyList.stream().collect(
        // 使用 Collectors.collectingAndThen 收集器,将流中的元素收集为一个列表
        Collectors.collectingAndThen(
                // 使用 Collectors.toCollection 收集器,将元素收集到一个 TreeSet 中
                Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(StorageDeliveryPrintExcelResp::getOmsOrderId))),
                // 使用 ArrayList::new 将 TreeSet 转换为 ArrayList
                ArrayList::new
        )
);

3、封装StreamUtils

java 复制代码
public class StreamUtils {

    public static <T> Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor) {
        Set<Object> seen = ConcurrentHashMap.newKeySet();
        return t -> seen.add(keyExtractor.apply(t));
    }

}

List<SalesOrder> collect = orderCompanyList.stream().filter(StreamUtils.distinctByKey(SalesOrder::getOmsOrderId))
                .filter(Objects::nonNull)
                .collect(Collectors.toList());
  1. public static <T> Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor) {

    这是一个公共静态方法,它是一个泛型方法,参数 T 表示元素的类型。它接受一个 Function 类型的参数 keyExtractor,这个函数用于提取元素的某个属性或标识,以便用于判断元素是否重复。

  2. Set<Object> seen = ConcurrentHashMap.newKeySet();

    这一行创建了一个线程安全的 Set 实例 seen,用于存储已经看到的元素的键(key)。这里使用了 ConcurrentHashMap.newKeySet() 来获取一个基于 ConcurrentHashMap 实现的线程安全的 Set,以确保在多线程环境下的安全性。

  3. return t -> seen.add(keyExtractor.apply(t));

    这一行返回了一个 Predicate<T>,该 Predicate 接受类型为 T 的元素 t,并根据 keyExtractor 提取的键来判断是否将该元素添加到 seen 集合中。如果 seen 集合中不存在该元素的键(即元素是第一次出现),则将该元素的键添加到 seen 集合中,并返回 true;否则返回 false,表示该元素已经存在,不需要再次添加。

总的来说,这段代码的作用是生成一个 Predicate,用于根据指定的键(通过 keyExtractor 函数提取)来判断元素是否重复,如果元素的键是第一次出现,则返回 true,否则返回 false。

相关推荐
岁岁岁平安2 分钟前
spring学习(spring-DI(字符串或对象引用注入、集合注入)(XML配置))
java·学习·spring·依赖注入·集合注入·基本数据类型注入·引用数据类型注入
武昌库里写JAVA5 分钟前
Java成长之路(一)--SpringBoot基础学习--SpringBoot代码测试
java·开发语言·spring boot·学习·课程设计
Q_192849990612 分钟前
基于Spring Boot的九州美食城商户一体化系统
java·spring boot·后端
张国荣家的弟弟29 分钟前
【Yonghong 企业日常问题 06】上传的文件不在白名单,修改allow.jar.digest属性添加允许上传的文件SH256值?
java·jar·bi
ZSYP-S41 分钟前
Day 15:Spring 框架基础
java·开发语言·数据结构·后端·spring
yuanbenshidiaos1 小时前
C++----------函数的调用机制
java·c++·算法
唐叔在学习1 小时前
【唐叔学算法】第21天:超越比较-计数排序、桶排序与基数排序的Java实践及性能剖析
数据结构·算法·排序算法
是小崔啊1 小时前
开源轮子 - EasyExcel01(核心api)
java·开发语言·开源·excel·阿里巴巴
ALISHENGYA1 小时前
全国青少年信息学奥林匹克竞赛(信奥赛)备考实战之分支结构(switch语句)
数据结构·算法
黄公子学安全1 小时前
Java的基础概念(一)
java·开发语言·python