【问题标题】:Java remove duplicate Object propertiesJava 删除重复的对象属性
【发布时间】:2021-11-04 17:19:36
【问题描述】:

我正在尝试返回没有重复属性的List<Object>(使用CSVRecord)。

我收到了这样一份 CSV:

brand;color
bmw;red
bmw;blue
jaguar;yellow
jaguar;red
mercedes;bleu
fiat;green

汽车类看起来像(例如):

@Builder
@Data
public class Car {

  private String brand;
  private List<String> color;

}

我有一个这样的方法(仅作为示例):

public List<Car> convert(List<CSVRecord> csvRecordList) {
    Map<Car, List<CSVRecord>> csvRecordsByCar = csvRecordList.stream()
        .collect(Collectors.groupingBy(csvRecord -> Car.builder()
            .brand(csvRecord.get("brand"))
            .color(Collections.singletonList(csvRecord.get("color")))
            .build()
        ));

    return csvRecordsByCar .entrySet().stream()
        .map((Map.Entry<Car, List<CSVRecord>> csvRecordByCar) ->
            Car.builder()
                .brand(csvRecordByCar.getKey().getBrand())
                .color(csvRecordByCar.getKey().getColor())
                .build()
        )
        .collect(Collectors.toList());
}

现在它返回给我一个带有重复品牌的Car 列表对象。我想要的是不要有重复的品牌并在列表中合并品牌的颜色,例如:

Car{
  brand: "bmw",
  color: ["red", "blue"]
}

我是java新手。

【问题讨论】:

  • 你能分享你的车课吗?

标签: java java-8 java-stream lombok


【解决方案1】:

您需要在分组后创建Car 对象。目前,由于您按Car 对象本身进行分组,因此结果列表中brand-color 的每个组合都会有一个Car 对象。首先,您只需按颜色分组,然后继续创建对象。

注意:假设在下面的代码中静态导入Collectors方法toList()mapping()groupingBy()

Map<String, List<String>> map 
    = csvRecordList.stream()
                   .collect(groupingBy(record -> record.get("brand"),
                                       mapping(record -> record.get("color"), 
                                               toList())));

// Now convert this map to list of Cars
return map.entrySet()
          .stream()
          .map(entry -> Car.builder()
                           .brand(entry.getKey())
                           .color(entry.getValue())
                           .build())
          .collect(toList());

【讨论】:

    【解决方案2】:

    在没有看到汽车类的情况下,我从函数的第一部分假设您是 groupingBy Car,这依赖于您实现 equalshashcode

    所以这可能就是你得到重复的原因

    Car{
      brand: "bmw",
      color: ["red"]
    }
    
    Car{
      brand: "bmw",
      color: ["blue"]
    }
    

    另一个要考虑的选项是groupBybrand 名称并收集colors 列表,然后将结果映射到Car 列表中。

    【讨论】:

      【解决方案3】:

      假设您的汽车类有颜色作为列表,使该类如下所示:

      public class Car {
      private String name;
      private List<String> color;
      }
      

      您需要在您的汽车类中添加以下方法,

      public void addColor(String color){
          if(null==this.color){
              this.color = new ArrayList<>();
          } 
         this.color.add(color);
      }
      

      试试这个:

          public List<Car> convert(List<CSVRecord> csvRecordList) {
      Map<String, List<CSVRecord>> csvRecordsByCar = csvRecordList.stream()
          .collect(Collectors.groupingBy(csvRecord -> csvRecord.get("brand")));
      
      List<Car> result= new ArrayList<>();
          for (Map.Entry mapElement : csvRecordsByCar.entrySet()) {
              String key = (String)mapElement.getKey();
              List<CSVRecord> value = (List<CSVRecord>) mapElement.getValue();
              Car car=new Car();
              car.setName(key);
              for (CSVRecord csvRecord2 : value) {
                  car.addColor(csvRecord2.get("color"));
              }
              result.add(car);
          }
           return result;
          }
      

      【讨论】:

      • 它正在删除重复的键,但也删除了它们的值
      • 你的 POJO 中添加 addColor 方法了吗?
      • 是的,我照你写的做了
      • 我已经在我的本地尝试过这个......它工作正常检查你是否缺少其他任何东西
      • this.color.add(color); 方法中的addColor 部分可以移到if 条件之外,因为它必须始终这样做。
      猜你喜欢
      • 1970-01-01
      • 2019-08-27
      • 1970-01-01
      • 2023-03-28
      • 1970-01-01
      • 2019-09-18
      • 2017-06-02
      • 1970-01-01
      • 2015-12-14
      相关资源
      最近更新 更多