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 分钟前
[java] JVM 内存泄漏分析案例
java·开发语言·jvm
yy_xzz6 分钟前
【数据结构】大话单链表
数据结构·链表
程序员鱼皮14 分钟前
前后端分离,千万别再搞错了!
java·前端·后端·计算机·程序员·编程·软件开发
澪吟28 分钟前
算法性能的核心度量:时间复杂度与空间复杂度全解析
数据结构·算法
Gu_yyqx28 分钟前
IDEA 中 Tomcat 部署 Java Web 项目
java·tomcat·maven
SimonKing29 分钟前
【开发者必备】Spring Boot 2.7.x:WebMvcConfigurer配置手册来了(五)!
java·后端·程序员
知兀34 分钟前
【Java】@Autowired警告问题,使用@RequiredArgsConstructor
java
闲云散1 小时前
WebClient 简述
java·后端
louisdlee.1 小时前
扫描线1:朴素扫描线
数据结构·c++·算法·扫描线
wudl55661 小时前
JDK 21性能优化详解
java·开发语言·性能优化