如何在不使用 forEach 的情况下在 Collectors.groupingBy() 之后对地图值进行分组
How to group map values after Collectors.groupingBy() without using forEach
我有一个 ProductDto 对象列表,我想使用 java 8 个流 Collectors.groupingBy() 将它们分组为相似的对象。对记录进行分组后,我想将相似的记录合并为单个 productDto。为此,我使用了 map.forEach 并获得了预期的结果,但我想避免 forEach 循环并想知道 java 8.
中的任何更好的解决方案
下面是我的主要 Class 代码片段。
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",8,null,"DELL_s002",null));
dtos.add(new ProductDto(1L,"DELL",8,null,null,"DELL_s003"));
dtos.add(new ProductDto(1L,"HP",8,"HP_s001",null,null));
dtos.add(new ProductDto(2L,"APPLE",16,"MAC_s001",null,null));
return dtos;
}
}
这是 ProductDto class 代码
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 中任何有效的替代或更好的解决方案都是最受欢迎的。
在 Rono 评论后我找到了答案所以发布了我在 getGroupedResult 方法中所做的答案并添加了一个新函数 合并两个产品。所以这可能对某人有帮助。
下面是更改后我的 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;
}
我有一个 ProductDto 对象列表,我想使用 java 8 个流 Collectors.groupingBy() 将它们分组为相似的对象。对记录进行分组后,我想将相似的记录合并为单个 productDto。为此,我使用了 map.forEach 并获得了预期的结果,但我想避免 forEach 循环并想知道 java 8.
中的任何更好的解决方案下面是我的主要 Class 代码片段。
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",8,null,"DELL_s002",null));
dtos.add(new ProductDto(1L,"DELL",8,null,null,"DELL_s003"));
dtos.add(new ProductDto(1L,"HP",8,"HP_s001",null,null));
dtos.add(new ProductDto(2L,"APPLE",16,"MAC_s001",null,null));
return dtos;
}
}
这是 ProductDto class 代码
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 中任何有效的替代或更好的解决方案都是最受欢迎的。
在 Rono 评论后我找到了答案所以发布了我在 getGroupedResult 方法中所做的答案并添加了一个新函数 合并两个产品。所以这可能对某人有帮助。 下面是更改后我的 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;
}