Search code examples
javajava-11micronaut

How can I remove a duplicate record from the list and mark it with an enum?


Explaining ... I receive the return of two lists of type MyDTO and add these two returns, in a single list. And these records are marked, in these first two returns with an Enum. Since the lists come from different places, I can have repeated records. And, if there is a repeated record, I must mark it with the specific type in Enum and leave only one record.

MyDTO:

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

My return class:

@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
    }
}

My Enum:

@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;
    }
}

So, how can I check if the item is repeated (returned in both lists) and mark it with the type of Enum 3?


Solution

  • Using Java Stream, a map an be built with a key representing someField and codMyDto and enums collected into set. After that the entries of the map are remapped to MyDto depending on the size/contents of the set.

    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());
        }
    

    It may be possible to use MyDto as a key instead of the raw list:

    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());
        }