Java8 Stream流中的Collectors.collectingAndThen()方法

1.用自定义的实现Collection的数据结构收集

Collectors.toCollection();

2.集合元素拼接

Collectors.Joining();

collectingAndThen(); //  收集之后继续做一些处理。
        .()中一般是Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(AssetInfo::getNumber)))
    public static class HeaderDto implements Serializable {

        private static final long serialVersionUID = 89423674447742L;

        private String version;

        @JSONField(name = "sys-code")
        private String sysCode;

        @JSONField(name = "biz-id")
        private String bizId;

        @JSONField(name = "biz-type")
        private String bizType;

        private Long timestamp;

        private String sign;

        public String getVersion() {
            return version;
        }

        public void setVersion(String version) {
            this.version = version;
        }

        public String getSysCode() {
            return sysCode;
        }

        public void setSysCode(String sysCode) {
            this.sysCode = sysCode;
        }

        public String getBizId() {
            return bizId;
        }

        public void setBizId(String bizId) {
            this.bizId = bizId;
        }

        public String getBizType() {
            return bizType;
        }

        public void setBizType(String bizType) {
            this.bizType = bizType;
        }

        public Long getTimestamp() {
            return timestamp;
        }

        public void setTimestamp(Long timestamp) {
            this.timestamp = timestamp;
        }

        public String getSign() {
            return sign;
        }

        public void setSign(String sign) {
            this.sign = sign;
        }
    }


    public static void main(String[] args) {
        List list = new ArrayList<>();
        HeaderDto dto1 = new HeaderDto();
        dto1.setBizId("01");
        dto1.setBizType("机构A");

        HeaderDto dto2 = new HeaderDto();
        dto2.setBizId("01");
        dto2.setBizType("机构A");

        HeaderDto dto3 = new HeaderDto();
        dto3.setBizId("01");
        dto3.setBizType("机构B");

        HeaderDto dto4 = new HeaderDto();
        dto4.setBizId("02");
        dto4.setBizType("机构C");

        list.add(dto1);
        list.add(dto2);
        list.add(dto3);
        list.add(dto4);

        // 分组后, 将value去重后拼接成 字符串,两个元素之间用 , 分割
        Map filter = list.stream()
                .collect(Collectors.groupingBy(HeaderDto::getBizId,
                        Collectors.mapping(HeaderDto::getBizType,
                                Collectors.collectingAndThen(Collectors.toSet(), e -> String.join(",", e)))));

// {01=机构A,机构B, 02=机构C}
        System.out.println(filter);
    }

3.收集器可以高效的复合起来,进行多级分组,多级分区和归约 


public static void main(String[] args) {
        List associatedAssetInfoList = new ArrayList<>();
        AssetInfo assetInfo = new AssetInfo();
        assetInfo.setNumber("001");
        assetInfo.setOldNumber("001001");
        AssetInfo assetInfo1 = new AssetInfo();
        assetInfo1.setNumber("001");
        assetInfo1.setOldNumber("001002");
        AssetInfo assetInfo2 = new AssetInfo();
        assetInfo2.setNumber("002");
        assetInfo2.setOldNumber("001001");
        AssetInfo assetInfo3 = new AssetInfo();
        assetInfo3.setNumber("003");
        assetInfo3.setOldNumber("001001");
        associatedAssetInfoList.add(assetInfo);
        associatedAssetInfoList.add(assetInfo1);
        associatedAssetInfoList.add(assetInfo2);
        associatedAssetInfoList.add(assetInfo3);

        if (!CollectionUtils.isEmpty(associatedAssetInfoList)) {
            // todo: 根据资产编号去重
            associatedAssetInfoList = associatedAssetInfoList.stream().collect(
                    Collectors.collectingAndThen(
                        Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(AssetInfo::getNumber))),
                            ArrayList::new)
            );
        }
        associatedAssetInfoList.forEach(e -> System.out.println(e));

        // 1-todo: 根据资产的编号和旧资产编号进行分组,即多属性进行分组
        Map, List> collect = associatedAssetInfoList.stream()
                .collect(Collectors.groupingBy(f -> Arrays.asList(f.getNumber(),f.getOldNumber())));

        // 1-todo: 实现原理不同,上面的是直接根据多个属性进行分组,下面是先根据number分组,再根据oldNumber分组,最终结果是map嵌套map
        Map>> collect = associatedAssetInfoList.stream()
                .collect(Collectors.groupingBy(AssetInfo::getNumber, Collectors.groupingBy(AssetInfo::getOldNumber)));

        // 2-map收集资产分类 -> 去重后 -> 收集后转换为集合
        List typeList = list.stream().map(TypeNameModelImportData::getTypeName).distinct()
                .collect(Collectors.toList()); // map收集资产分类 -> 去重后 -> 收集后转换为集合
        
        // 2-map收集资产分类的名称 -> 取set集合方式来去重
        Set typeSet = valueList.stream().map(TypeNameModelImportData::getTypeName)
                        .collect(Collectors.toSet()); 

        // map收集资产分类的名称 -> 去重 取set集合
        Map map = p2pIdList.stream().filter(Objects::nonNull).collect(
                Collectors.groupingBy(p2pId -> p2pId, Collectors.counting())); 
        
        // todo: 过滤器 Objects::nonNull 过滤掉null值 -> 根据p2pId分组
        Map assetNameKV = allNameList.stream()
                .collect(Collectors.toMap(SysAssetName::getName, SysAssetName::getId)); // excel中所有的资产名称对应的 name-id        

    }


4.事例

//多个元素
List transfers = paOrSafeStockTransfers.stream().collect(
                    Collectors.collectingAndThen(
                            Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(o -> o.getChBuDealerCode() + ";" + o.getChBuProductCode() + ";" + o.getDrawingNumber()))), ArrayList::new)
            );

//单个元素
List allYearTargetTypePos = this.selectList(new EntityWrapper().eq("SYFW", RangeEnum.all.getValue())
                .or().eq("CJBMID", user.getDepartmentId()));
        typePoList.addAll(allYearTargetTypePos);
//        去掉重复的任务
        newList = typePoList.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(
                () -> new TreeSet<>(Comparator.comparing(YearTargetTypePo::getId))), ArrayList::new));

//
@Test
public void collectingAndThenExample() {
    List list = Arrays.asList(1, 2, 3, 4);
    Double result = list.stream().collect(Collectors.collectingAndThen(Collectors.averagingLong(v -> {
                System.out.println("v--" + v + "--> " + v * 2);
                return v * 2;
            }),
            s -> {
                System.out.println("s--" + s + "--> " + s * s);
                return s * s;
            }));
    System.out.println(result);
}

输出:
v--1--> 2
v--2--> 4
v--3--> 6
v--4--> 8
s--5.0--> 25.0
25.0

你可能感兴趣的:(list,数据结构)