Home > Enterprise >  Java 8 Stream remove "almost" duplicates from list?
Java 8 Stream remove "almost" duplicates from list?

Time:04-01

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.

CodePudding user response:

This is what you're looking for

   Map<Long, Optional<Class1>> mapFiltered = list.stream()
                .collect(Collectors.groupingBy(x -> x.getId(),
                        Collectors.maxBy(Comparator.comparingInt(x -> x.getList().size()))));

Here, I've also added a simple main test

public class Main {
    public static void main(String[] args) {
        ArrayList<Class2> test1List = new ArrayList<>();
        test1List.add(new Class2(1000L));
        test1List.add(new Class2(2000L));
        test1List.add(new Class2(3000L));
        Class1 test1 = new Class1(100L, test1List);

        ArrayList<Class2> test2List = new ArrayList<>();
        test2List.add(new Class2(1000L));
        Class1 test2 = new Class1(100L, test2List);

        ArrayList<Class2> test3List = new ArrayList<>();
        test3List.add(new Class2(10000L));
        test3List.add(new Class2(20000L));
        test3List.add(new Class2(30000L));
        Class1 test3 = new Class1(200L, test3List);

        ArrayList<Class2> test4List = new ArrayList<>();
        test4List.add(new Class2(10000L));
        test4List.add(new Class2(20000L));
        Class1 test4 = new Class1(200L, test4List);

        ArrayList<Class2> test5List = new ArrayList<>();
        test5List.add(new Class2(10000L));
        Class1 test5 = new Class1(200L, test5List);

        Class1 test6 = new Class1(300L, new ArrayList<>());


        List<Class1> list = new ArrayList<>();
        list.add(test1);
        list.add(test2);
        list.add(test3);
        list.add(test4);
        list.add(test5);
        list.add(test6);

        for (Class1 c1 : list) {
            System.out.println(c1);
        }

        Map<Long, Optional<Class1>> mapFiltered = list.stream()
                .collect(Collectors.groupingBy(x -> x.getId(),
                        Collectors.maxBy(Comparator.comparingInt(x -> x.getList().size()))));

        System.out.println("---------------- RESULT ----------------");
        for (Long id : mapFiltered.keySet()) {
            if (mapFiltered.get(id).isPresent()) {
                System.out.println(mapFiltered.get(id).get());
            }
        }
    }
}

class Class1 {
    private Long id;
    private List<Class2> list;

    public Class1(Long id, List<Class2> list) {
        this.id = id;
        this.list = list;
        if (this.list == null) {
            this.list = new ArrayList<>();
        }
    }

    public Long getId() {
        return id;
    }

    public List<Class2> getList() {
        return list;
    }

    @Override
    public String toString() {
        StringBuilder str = new StringBuilder();
        str.append(id);
        str.append(" => [");
        for (Class2 c2 : list) {
            str.append(c2.toString());
            str.append(" ");
        }
        if (list.size() > 0) {
            str.deleteCharAt(str.length() - 1);
        }
        str.append("]");

        return str.toString();
    }
}

class Class2 {
    private Long id;

    public Class2(Long id) {
        this.id = id;
    }

    public Long getId() {
        return id;
    }

    @Override
    public String toString() {
        return String.valueOf(id);
    }
}
  •  Tags:  
  • java
  • Related