stream流根据集合某个字段去重

发布时间 2023-03-23 12:44:20作者: cherrymint

//stream流根据集合某个字段去重,流.filter(distinctByKey)

点击查看代码
 定义方法
   public static <T> Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor) {
        Map<Object, Boolean> seen = new ConcurrentHashMap<>();
        return t -> seen.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null;
    }


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

        例:
        HashMap<String, List<InvoiceOcrItemsDTO>> itemsMap = new HashMap<>();
        //按号码分组,这里分组可以重复,此处测试用例key相同value不同
        Map<String, List<InvoiceOcrDTO>> invoiceMap = invoiceOcrInfo.stream().collect(Collectors.groupingBy(e -> e.getNumber()));
        for (Map.Entry<String, List<InvoiceOcrDTO>> map : invoiceMap.entrySet()) {
            List<InvoiceOcrItemsDTO> items = new ArrayList<>();
            map.getValue().forEach(e -> {
                //所有行放进集合再取给map
                items.addAll(e.getItems());
            });
            itemsMap.put(map.getKey(), items);
        }
        //去重
        List<InvoiceOcrDTO> result = invoiceOcrInfo.stream().filter(distinctByKey(InvoiceOcrDTO::getNumber)).collect(Collectors.toList());
        result.forEach(e->{
            //如果去重后的元素在分组中
            if(invoiceMap.containsKey(e.getNumber())){
                String name = itemsMap.get(e.getNumber()).stream().map(InvoiceOcrItemsDTO::getName).collect(Collectors.toList()).toString();
                e.setItemNames(name);
                e.setItems(itemsMap.get(e.getNumber()));
            }
        });