0

I have 2 classes:

@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class FirstDTO {

    private Long id;

    @Builder.Default
    private List<SecondDTO> secondDTOs = Lists.newArrayList();
}

@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class SecondDTO  {
    
    private Long id;
    private String code;
}

My controller returns List of FirstDTO:

ResponseEntity<List<FirstDTO>> add(List<MySampleDTO> dtoList);

The controller can get a List what will produces multiple FirstDTO as response. In FirstDTO I include the id of it and a List<SecondDTO>. The problem is that it can happen that the data will be redundant:

[
  {
    "id": 1,
    "secondDTO": [
      {
        "id": 200,
        "code": "MY_200_TEST_CODE"
      }
    ]
  },
  {
    "id": 1,
    "secondDTO": [
      {
        "id": 200,
        "code": "MY_200_TEST_CODE"
      },
      {
        "id": 300,
        "code": "MY_300_TEST_CODE"
      }
    ]
  }
]

As you can see the second object of the json would be enough as response because it contains the first object. So I would like to use java 8 streams (or any other method) that will transform the list I showed earlier, to this:

[
  {
    "id": 1,
    "secondDTO": [
      {
        "id": 200,
        "code": "MY_200_TEST_CODE"
      },
      {
        "id": 300,
        "code": "MY_300_TEST_CODE"
      }
    ]
  }
]

So basically I need a method that groups FirstDTOs based on it's id and then save only FirstDTO with given id that has the longest list of SecondDTOs

Thanks in advance.

stacktrace2234
  • 1,172
  • 1
  • 12
  • 22
  • 2
    I think it duplicate question. Please check this link https://stackoverflow.com/questions/29670116/remove-duplicates-from-a-list-of-objects-based-on-property-in-java-8 – Ranjitsinh Apr 01 '22 at 09:02

1 Answers1

1

Here is an example, it's readable and easy to understand, the first group by id, create a new object with the first element in the list and then joins all the SecondDTO's classes to finally collect the FirstDTO.

List<FirstDTO> result = oldlist.stream().collect(Collectors.groupingBy(FirstDTO::getId)).values().stream()
                .map(grouped -> new FirstDTO(grouped.get(0).getId(), grouped.stream().map(FirstDTO::getSecondDTOs)
                        .flatMap(List::stream).distinct().collect(Collectors.toList())))
                .collect(Collectors.toList());

Before

[
    {
        "id": 1,
        "secondDTOs": [
            {
                "code": "MY_200_TEST_CODE",
                "id": 200
            }
        ]
    },
    {
        "id": 1,
        "secondDTOs": [
            {
                "code": "MY_200_TEST_CODE",
                "id": 200
            },
            {
                "code": "MY_300_TEST_CODE",
                "id": 300
            }
        ]
    },
    {
        "id": 2,
        "secondDTOs": [
            {
                "code": "aMY_200_TEST_CODE",
                "id": 1200
            },
            {
                "code": "aMY_300_TEST_CODE",
                "id": 1300
            }
        ]
    }
]

After

[
    {
        "id": 1,
        "secondDTOs": [
            {
                "code": "MY_200_TEST_CODE",
                "id": 200
            },
            {
                "code": "MY_300_TEST_CODE",
                "id": 300
            }
        ]
    },
    {
        "id": 2,
        "secondDTOs": [
            {
                "code": "aMY_200_TEST_CODE",
                "id": 1200
            },
            {
                "code": "aMY_300_TEST_CODE",
                "id": 1300
            }
        ]
    }
]
Sibin Rasiya
  • 1,132
  • 1
  • 11
  • 15