【问题标题】:Java 8 filter duplicate objects in a list [duplicate]Java 8过滤列表中的重复对象[重复]
【发布时间】:2021-07-07 02:41:20
【问题描述】:

我有一个数组列表:

List<EmpData> data;

class Emp {

    Integer id;
    String department;
    String action;

    // getters and setters
}

我得到如下数据:

1, Food, Add
1, Food, Remove
2, Food, Add
2, Auto, Remove
3, Electric, Add
3, Electric, Remove
3, Food, Remove

我想删除id和部门相同的所有记录。

那是对于 EmpId 1 there & department food,有 2 条记录,所以删除它们。

这样结果列表将只包含:

2, Food, Add
2, Auto, Remove
3, Food, Remove

如何在 java 8 中过滤这个列表?

【问题讨论】:

  • 要明确 - 你想消除相应的“添加/删除对”吗?
  • @TomHANAX,是的,但如果 id 和部门相同,我想删除。

标签: java java-stream


【解决方案1】:

嗯,你可以排序,然后删除所有后续:

var sorted = list.stream().sort(Comparator.comparing(EmpData::getId).thenComparing(EmpData::getDepartment)).collect(Collectors.toList());

for(int i = 0; i < sorted.size() - 1; i++){
   var next = sorted.at( i + 1 );
   var current = sorted.at( i );
   if(current.getId().equals(next.getId()) && current.getDepartment().equals(next.getDepartment())){
      sorted.remove(i);
      i--; // check for next element
   }
}

【讨论】:

  • 注意 - 当有多个记录时,这将不起作用,例如 3 次“3,Electric,Add”和 2 次“3,Electric,Remove”。但不知道会不会是这样。也可以很容易地修复。
  • @TomHANAX 为什么?我不明白为什么action 会引起问题...最后,OP 什么来删除 id-departement 的重复项...操作应该无关紧要吗?
  • @AlbertoSinigaglia。谢谢,我试试这个。只是为了突出它的stream().sorted(),对吧?
  • @AlbertoSinigaglia 好的,我没有在那里写好例子,但想象一下项目不是“成对”的,​​极端的例子是 1 个添加和 10 个删除。据我了解,此算法不会搜索“真实”对,因此您最终会删除一次,但实际上已删除了 10 次;)我并不是说这是一个问题,但它可能是。我明白这一点,我们正在寻找按 id 和部门分组的对应对。但也许我误解了这个问题。
【解决方案2】:

首先,构建一个 Id/Department 组合存在次数的地图。

然后删除所有计数大于1的条目。

例子

List<EmpData> data = List.of();

TreeMap<EmpData, Long> counts = data.stream().collect(Collectors.groupingBy(
        Function.identity(),
        () -> new TreeMap<>(Comparator.comparing(EmpData::getId)
                                  .thenComparing(EmpData::getDepartment)),
        Collectors.counting()));
data.removeIf(e -> counts.get(e) > 1);

【讨论】:

    【解决方案3】:
           data.stream().distinct().collect(Collectors.toList());
    

    【讨论】:

    • 如果 equals 方法不是 OP 需要的,这将不起作用......最好的解决方法是顶级使用 distinctByKey 这将需要一个新的第二类作为返回类型
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-04-09
    • 1970-01-01
    • 2010-12-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多