如何在不使用forEach的情况下对Collectors.groupingBy之后的地图值进行分组

问题描述

我有一个ProductDto对象的列表,我想使用Java 8流Collectors.groupingBy()将它们分组。将记录分组后,我想将类似的记录合并为单个productDto。为此,我使用了map.forEach并获得了预期的结果,但是我想避免forEach循环,并且想知道Java 8中的任何更好的解决方案。

下面是我的主要课程代码段。

public class GroupTest {

public static void main(String[] args) {
    GroupTest t=new GroupTest();
    List<ProductDto> inputDtos=t.createInputData();
    List<ProductDto> resultDtos=t.getGroupedResult(inputDtos);
    //writing to Excel
}

private List<ProductDto> getGroupedResult(List<ProductDto> inputDtos) {
    
    Map<Object,List<ProductDto>> groupedMap = inputDtos.stream()
            .collect(Collectors.groupingBy(ProductDto::groupSimilarProductIdentifier));
    
    List<ProductDto> resultProductDtos=new ArrayList<>();

    groupedMap.forEach((key,dtos) -> {
        if (dtos.size() > 1) {
            ProductDto productDto = dtos.get(0);
            dtos.forEach(dto -> {
                if (dto.getLap1() != null) {
                    productDto.setLap1(dto.getLap1());
                } else if (dto.getLap2() != null) {
                    productDto.setLap2(dto.getLap2());
                } else if (dto.getLap3() != null) {
                    productDto.setLap3(dto.getLap3());
                }
            });
            resultProductDtos.add(productDto);
        } else {
            resultProductDtos.addAll(dtos);
        }
    });
    
    return resultProductDtos;
}

private List<ProductDto> createInputData(){
    List<ProductDto> dtos=new ArrayList<>();
    dtos.add(new ProductDto(1L,"DELL",8,"DELL_s001",null,null));
    dtos.add(new ProductDto(1L,"DELL_s002","DELL_s003"));
    dtos.add(new ProductDto(1L,"HP","HP_s001",null));
    dtos.add(new ProductDto(2L,"APPLE",16,"MAC_s001",null));
    return dtos;
}
}

这是ProductDto类代码

public class ProductDto {
private Long userId;
private String manufacter;
private int ram;
private String lap1;
private String lap2;
private String lap3;

public ProductDto(Long userId,String manufacter,int ram,String lap1,String lap2,String lap3) {
    super();
    this.userId = userId;
    this.manufacter = manufacter;
    this.ram = ram;
    this.lap1 = lap1;
    this.lap2 = lap2;
    this.lap3 = lap3;
}
//getters and Setters

public List<Object> groupSimilarProductIdentifier() {
    return Arrays.asList(userId,manufacter,ram);
}
}

下面的屏幕快照图像显示了输入和输出记录。输出记录正是我想要的结果。非常欢迎Java 8中任何有效的替代解决方案或更好的解决方案。

enter image description here

解决方法

Rono 评论后,我找到了答案,因此发布了我在 getGroupedResult 方法中所做的回答,并添加了新功能 mergetwoProduct 。因此,这可能会对某人有所帮助。 下面是更改后我的getGroupedResult和mergetwoProduct方法的代码。

private List<ProductDto> getGroupedResult(List<ProductDto> inputDtos) {
    List<ProductDto> productdtos= new ArrayList<>(inputDtos.stream().collect(
            Collectors.toMap(ProductDto::groupSimilarProductIdentifier,e -> e,(a,b) -> mergetwoProduct(a,b)))
            .values());
    return productdtos;
}

private ProductDto mergetwoProduct(ProductDto p1,ProductDto p2) {
    if (p2.getLap1() != null) {
        p1.setLap1(p2.getLap1());
    } else if (p2.getLap2() != null) {
        p1.setLap2(p2.getLap2());
    } else if (p2.getLap3() != null) {
        p1.setLap3(p2.getLap3());
    }
    return p1;
}

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...