【问题标题】:How to find duplicate elements in a Stream in Java如何在 Java 中的 Stream 中查找重复元素
【发布时间】:2021-08-04 18:29:00
【问题描述】:

我正在尝试在地图值中查找重复条目。但问题是值列表具有多个属性/属性。基本上,如果一个标题在数据库中出现多次,我会将一个条目标记为唯一条目,并将其余条目标记为重复条目。

这是我当前的代码:

// I have a Map that looks like...

host1 : id | title | host1 | url | state | duplicate
        id | title | host1 | url | state | duplicate

host2 : id | title | host2 | url | state | duplicate
        id | title | host2 | url | state | duplicate


    for (Map.Entry<String, List<Record>> e : recordsByHost.entrySet()) {
      boolean executed = false;
      for (Record r : e.getValue()) {
        int frequency = Collections.frequency(
          e
            .getValue()
            .stream()
            .map(Record::getTitle)
            .collect(Collectors.toList()),
          r.getTitle()
        );
        if ((frequency > 1) && (!executed)) {
          markDuplicates(r.getId(), r.getTitle());
          executed = true;
        } else {
          executed = false;
        }

问题是当频率大于 2(三个具有相同标题的记录)时,该行评估为 false,并将第三个记录/第二个重复视为“唯一”。

我一直在尝试修改我的逻辑,但我担心我被卡住了。任何让我摆脱困境的帮助/建议将不胜感激。

【问题讨论】:

  • 你一定要使用流吗?我认为响应从 Set.add 返回的布尔值会更有用。
  • @VGR - 不一定。 “响应从 Set.add 返回的布尔值”到底是什么意思?您有可以分享的有用文章吗?

标签: java


【解决方案1】:

Set.add(实际上是 Collection.add)当且仅当该值实际添加到 Set 时才返回 true。由于 Set 始终强制唯一性,因此您可以使用它来查找重复项:

void markDuplicates(Iterable<? extends Record> records) {
    Set<String> foundTitles = new HashSet<>();

    for (Record r : records) {
        String title = r.getTitle();
        if (title != null && !foundTitles.add(title)) {
            // title was not added, because it's already been found.
            markAsDuplicate(r);
        }
    }
}

【讨论】:

  • 每天学习新东西!感谢那!我没有完全使用您提供的所有代码,但我使用的是 set.add() 而不是 boolean = 已执行,我的所有单元测试现在都可以工作了! :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-05-17
  • 2020-06-28
  • 2020-08-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-02-24
相关资源
最近更新 更多