【问题标题】:How can I remove a duplicate record from the list and mark it with an enum?如何从列表中删除重复记录并用枚举标记它?
【发布时间】:2023-03-19 10:59:01
【问题描述】:

解释...我收到两个MyDTO 类型列表的返回,并将这两个返回添加到一个列表中。并且这些记录被标记,在前两个返回中带有Enum。 由于列表来自不同的地方,我可以重复记录。 并且,如果有重复记录,我必须在Enum中标明具体类型,只留下一条记录。

MyDTO:

@Builder
@AllArgsConstructor
@NoArgsConstructor
@EqualsAndHashCode(exclude = {"myEnum","someField"})
@Getter
@Setter
@ToString
public class MyDTO {
    private String someField;
    private MyEnum myEnum;
    private Long codMyDto;
}

我的返程班:

@Slf4j
@Singleton
@RequiredArgsConstructor
public class MyCreateContextClass {

    @Override
    protected List<MyDTO> myMainMethod() throws Exception {
        List< MyDTO > myDTOList = new ArrayList<>();

        myDTOList.addAll(firstReturnMyDTO());
        myDTOList.addAll(secondReturnMyDTO());

        // Mark the repeated items with type 3 of the Enum and make them unique.
       // How to do that ?

        return myDTOList; // My return must have unique items with correct enum
    }

    private List<MyDTO> firstReturnMyDTO() throws Exception {    
        return returnFirstListFromDTO.returnDTO(); // here my Enum is 1
    }

    private List<MyDTO> secondReturnMyDTO() throws Exception {
        return returnSecondListFromDTO.returnDTO(); // here my Enum is 2
    }
}

我的枚举:

@Getter
public enum MyEnum {

    MYFIRSTYTPE(1, “first”), // first addAll
    MYSECONDTYPE(2, “second”), // second addAll
    TWORETURNS(3, “all”); // in case the item is on both lists.

    private Integer key;
    private String value;

    MyEnum(Integer key, String value) {
        this.key = key;
        this.value = value;
    }

    public static MyEnum getEnum(Integer key) {
        for (MyEnum myEnum : MyEnum.values()) {
            if (myEnum.getKey().equals(key)) {
                return myEnum;
            }
        }
        return MyEnum.MYFIRSTYTPE;
    }
}

那么,如何检查该项目是否重复(在两个列表中都返回)并将其标记为Enum 3 的类型?

【问题讨论】:

    标签: java java-11 micronaut


    【解决方案1】:

    使用 Java Stream,可以使用代表 someFieldcodMyDto 的键构建映射,并将枚举收集到集合中。之后,根据集合的大小/内容,映射的条目将重新映射到 MyDto

    protected List<MyDTO> myMainMethod() throws Exception {
        return Stream.concat(firstReturnMyDTO().stream(), secondReturnMyDTO().stream())
                .collect(Collectors.groupingBy(
                    dto -> Arrays.asList(dto.getSomeField(), dto.getCodMyDto()), // key w/o enum
                    Collectors.mapping(MyDto::getMyEnum, Collectors.toSet())
                )) // map of List<?> key, Set<MyEnum>
                .entrySet().stream()
                .map(e -> new MyDto(
                    e.getKey().get(0), // someField from key
                    e.getValue().size() > 1 ? MyEnum.TWORETURNS 
                        : e.getValue().contains(MyEnum.MYSECONDTYPE) ? MyEnum.MYSECONDTYPE
                        : MyEnum.MYFIRSTTYPE,
                    e.getKey().get(1) // myCodDto from key 
                ))
                .collect(Collectors.toList());
        }
    

    可以使用MyDto 作为键而不是原始列表:

    protected List<MyDTO> myMainMethod() throws Exception {
        return Stream.concat(firstReturnMyDTO().stream(), secondReturnMyDTO().stream())
                .collect(Collectors.groupingBy(
                    dto -> new MyDto(dto.getSomeField(), null, dto.getCodMyDto()), // key w/o enum
                    Collectors.mapping(MyDto::getMyEnum, Collectors.toSet())
                )) // map of MyDto key with null myEnum, Set<MyEnum>
                .entrySet().stream()
                .map(e -> new MyDto(
                    e.getKey().getSomeField(), // someField from key
                    e.getValue().size() > 1 ? MyEnum.TWORETURNS 
                        : e.getValue().contains(MyEnum.MYSECONDTYPE) ? MyEnum.MYSECONDTYPE
                        : MyEnum.MYFIRSTTYPE,
                    e.getKey().getCodMyDto() // myCodDto from key 
                ))
                .collect(Collectors.toList());
        }
    

    【讨论】:

      【解决方案2】:

      这样的?

      for(int i = 0; i< list.size(); i++) {
                  for(int j = i+1; j<list.size(); j++) {
                      if(list.get(i).equals(list.get(j))) {
                          list.get(i).myEnum = MyEnum.TWORETURNS;
                          list.remove(j);
                          break;
                      }
                  }
                  
              }
      

      在 MyDTO 中重写 'equals' 方法或添加特定比较。

      【讨论】:

        【解决方案3】:
        List<MyDTO> first = firstReturnMyDTO();
        List<MyDTO> second = secondReturnMyDTO();
        List< MyDTO > myDTOList = new ArrayList<>(first);
        Set<MyDTO> uniqueSet = new HashSet<>();  
        
        //remove from myDTOList those who are not present in second
        myDTOList.retainAll(second);
        //remove from first those who are present in myDTOList
        first.removeAll(myDTOList);
        //remove from second those who are present in myDTOList
        second.removeAll(myDTOList);
        
        //get the unique values
        first.addAll(second); 
        
        //handle the duplicates - stored in myDTOList
        //adding them to the set will remove the duplicates. 
        //Then, mark them with enum 3
         uniqueSet.addAll(myDTOList);
         for (MyDTO m : uniqueSet)
             m.myEnum = MyEnum.TWORETURNS
        //add the uniques to the set
        uniqueSet.addAll(first);
        
        //if wanted, convert to list
        List<MyDTO> nonDuplicateList = new ArrayList<>(uniqueSet);
        

        现在nonDuplicateList 只包含非重复条目。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-01-07
          • 2017-02-02
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多