首页 > 解决方案 > 从 Java 8 中基于多个属性的对象列表中删除重复项

问题描述

我想比较 getCode 和 getMode 并找到重复的记录。

然后还有一个产品属性 getVode 在两条记录中始终具有不同的值(真或假)。

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

我在下面尝试过,但它只找到重复项:

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

因此,当我发现重复记录时,我想检查 getVode 值为 false 并将其从列表中删除。任何帮助,将不胜感激?

标签: javajava-8java-stream

解决方案


据我了解,只有当元素是重复的并且它们的getVode方法返回时,您才想删除元素false

我们可以从字面上做到这一点。首先,我们必须确定哪些元素是重复的:

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

然后,删除满足条件的那些:

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

或者,不修改旧列表:

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

这也可以通过 Stream 操作完成:

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

推荐阅读