Search code examples
javajava-8java-stream

Remove duplicates from a list of objects based multiple attributes in Java 8


I want to compare getCode & getMode and find duplicate records.

Then there is one more product attribute getVode which always has different value(either true or false) in both records.

P1   getCode  getMode  getVode
1    001      123      true
P2   getCode  getMode  getVode
2    001      123      false

I tried below but it only finds duplicates:

List<ProductModel> uniqueProducts = productsList.stream()
    .collect(Collectors.collectingAndThen(
        toCollection(() -> new TreeSet<>(
            Comparator.comparing(ProductModel::getCode)
                .thenComparing(ProductModel::getMode)
        )),
        ArrayList::new));

So when I find duplicates records, I want to check the getVode value which is false and remove it from list. Any help would be appreciated?


Solution

  • As far as I understood, you want to remove elements only if they are a duplicate and their getVode method returns false.

    We can do this literally. First, we have to identify which elements are duplicates:

    Map<Object, Boolean> isDuplicate = productsList.stream()
        .collect(Collectors.toMap(pm -> Arrays.asList(pm.getCode(), pm.getMode()),
                                  pm -> false, (a, b) -> true));
    

    Then, remove those fulfilling the condition:

    productsList.removeIf(pm -> !pm.getVode()
                             && isDuplicate.get(Arrays.asList(pm.getCode(), pm.getMode())));
    

    Or, not modifying the old list:

    List<ProductModel> uniqueProducts = new ArrayList<>(productsList);
    uniqueProducts.removeIf(pm -> !pm.getVode()
                               && isDuplicate.get(Arrays.asList(pm.getCode(), pm.getMode())));
    

    which can also be done via Stream operation:

    List<ProductModel> uniqueProducts = productsList.stream()
        .filter(pm -> pm.getVode()
                  || !isDuplicate.get(Arrays.asList(pm.getCode(), pm.getMode())))
        .collect(Collectors.toList());