Issue
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());
}
Answered By - Nowhere Man
Answer Checked By - Dawn Plyler (JavaFixing Volunteer)