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。

相关推荐
一颗花生米。20 分钟前
深入理解JavaScript 的原型继承
java·开发语言·javascript·原型模式
问道飞鱼20 分钟前
Java基础-单例模式的实现
java·开发语言·单例模式
C++忠实粉丝3 小时前
前缀和(8)_矩阵区域和
数据结构·c++·线性代数·算法·矩阵
ZZZ_O^O3 小时前
二分查找算法——寻找旋转排序数组中的最小值&点名
数据结构·c++·学习·算法·二叉树
ok!ko4 小时前
设计模式之原型模式(通俗易懂--代码辅助理解【Java版】)
java·设计模式·原型模式
代码雕刻家4 小时前
数据结构-3.9.栈在递归中的应用
c语言·数据结构·算法
2402_857589364 小时前
“衣依”服装销售平台:Spring Boot框架的设计与实现
java·spring boot·后端
吾爱星辰5 小时前
Kotlin 处理字符串和正则表达式(二十一)
java·开发语言·jvm·正则表达式·kotlin
哎呦没6 小时前
大学生就业招聘:Spring Boot系统的架构分析
java·spring boot·后端
Kalika0-06 小时前
猴子吃桃-C语言
c语言·开发语言·数据结构·算法