【问题标题】:What is the most efficient algorithm to detect and remove duplicates in a Collection? [closed]检测和删除集合中重复项的最有效算法是什么? [关闭]
【发布时间】:2017-03-31 12:01:49
【问题描述】:

在任何集合中检测和删除重复项的最有效方法是什么?我使用以下方法:

static class Link{
    Link(Link next1,Object val1){
        next = next1;
        val = val1;
    }
    Link next;
    Object val;
}
public static void removeDuplicates(Collection<?> collection){
    Link link = null;
    Iterator<?> itr = collection.iterator();
    a: while(itr.hasNext()){//Iterate the parameter Collection or corrupted Set
        Object obj = itr.next();
        Link c = link;
        while(c != null){
            if(obj.equals(c.val)){
                itr.remove();//Duplicate found!
                continue a;
            }
            c = c.next;
        }
        link = new Link(link,obj);
    }
}

是否有更快(或更好)的方法来删除重复项?

【问题讨论】:

  • 为什么要把可变对象放在一个集合中,然后操作它们的内容?你为什么要忽略警告这样做?您要做什么,可能有比在损坏设备时不断检查您的设备更好的方法。
  • 从集合中移除对象 -> 操作对象 -> 将对象添加到集合中
  • 解决问题的最快方法是退后一步,看看你即将制造的烂摊子;然后重新考虑您的方法并找到更好的解决方案。其他任何事情都是进入混乱的快速路线。关键是:Set 在添加 新对象时决定事情。在已添加的对象上完全“重新计算”自身的想法绝对对于集合类(恕我直言)是“外星人”。
  • 正如 Kayaman 已经说过的,如果 hashCode()equals() 可能会受到修改的影响。您遇到的问题只是其中的一个指标。
  • 顺便说一句:“我使用 HashSet 来操作一组 mutalbe 对象” - 你如何使用一组来操作对象?我猜你的意思是你正在操纵那个集合in的对象,不是吗?如果是这样,您可以尝试构建一个新集合,即迭代集合,删除对象(或在循环结束时清除原始集合),操作它们并将它们添加到新集合中。这应该会自动处理重复项。

标签: java collections


【解决方案1】:

如果您更改基于散列的集合中的对象,从而违反了散列码/等于合同,则该集合的行为是未指定的。对于 API,当然不能保证具有“类似”的语义。因此,规范(即 javadoc)将保证正常工作。

在实践中,最有可能工作的解决方案是迭代集合条目并将它们添加到新的(空)集合中。使用 addAll 将是等效的。这(当然)非常昂贵。

但真正的解决方案是从一开始就避免遇到问题。如果您将可变对象放入依赖于稳定相等和哈希码或稳定排序的集合中,则在对其进行变异之前将其删除;例如

set.remove(e);
e.mutate();
set.add(e);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-01-24
    • 1970-01-01
    • 1970-01-01
    • 2021-07-19
    • 2020-01-21
    • 2010-11-05
    相关资源
    最近更新 更多