【问题标题】:JAVA Finding duplicate values in TreeMap and getting key of same elementsJAVA在TreeMap中查找重复值并获取相同元素的键
【发布时间】:2014-12-06 13:42:58
【问题描述】:

我尝试在论坛中搜索答案,但找不到问题的解决方案。我有代表多边形的 TreeMap 。我的第一个任务是返回具有特定值的元素的键,第二个任务是返回所有重复的顶点。这是我尝试实现的代码和方法:

private SortedMap<String, Vertex2D> vertices = new TreeMap<String, Vertex2D>();

//adds vertex to map
public void addVertex(String label, Vertex2D vert){
    if(label == null){
        throw new NullPointerException("label");
    }
    if(vert == null){
        throw new NullPointerException("vert");
    }
    vertices.put(label, vert);
}

//这些方法不正常

public Collection<String> getLabels(Vertex2D vert){
    SortedSet<String> labels = new TreeSet<String>();
    for(Map.Entry<String, Vertex2D> entry : vertices.entrySet()){
        if(entry.getValue() == vert) {
            labels.add(entry.getKey());
        }
    }
    return labels;
}


public Collection<Vertex2D> duplicateVertices(){
    List<Vertex2D> list = new ArrayList<Vertex2D>(vertices.values());
    List<Vertex2D> duplicated = new ArrayList<Vertex2D>();
    for(int i = 0; i < list.size() - 1; i++){
            for(int j = i+1; j < list.size() - 1; j++){
                if(!duplicated.contains(list.get(j)) && list.get(j) == list.get(i)){
                    duplicated.add(list.get(j));
                }
            }
        }
    return duplicated;
}

感谢每一个帮助!

【问题讨论】:

  • 您能告诉我们什么不完全正常,您期望什么以及您得到什么?很高兴知道当您调用“addVertex”时您将什么作为“标签”:它们是否是唯一值?另外,当你写“if(entry.getValue() == vert)”时,你真的是指“==”,而不是“.equals()”吗?第一个是对象引用比较,第二个是对象相等。
  • 除了您遇到的问题之外,您的实施效率不高。您不应在所有顶点上循环两次(平方)以查找重复项。它的复杂度是 o(n²),而你可以有 o(n)。但这是另一个问题
  • 是的,我意识到我的描述不正确。 Equals() 是问题所在,我不是优秀的程序员:D(顺便说一句,我不知道如何使方法 duplicateVertices 更有效。我很欣赏任何想法)

标签: java collections map treemap


【解决方案1】:

如何创建第二个 TreeMap 或 HashMap

HashMap<Vertex2D, ArrayList<String>>

然后,您在上面的示例中遍历第一个 TreeMap,并为每个元素检查是否已经有一个条目,如果是,只需将键添加到这个字符串条目列表中。

最后,您遍历此映射并检查每个条目是否列表有多个条目,如果是这种情况,您有重复项(并做任何您想做的事情)。

可能还有其他性能更好的方法,但这种方法会起作用。

有一个similar topic here

【讨论】:

  • 我终于找到了为什么我的代码不起作用。问题是我在这两种方法中都使用了 == 。我应该使用在 Vertex2D 类中实现的 equals()。愚蠢的我:D
  • 哦,好吧,在这种情况下使用你的版本。 :)
【解决方案2】:

只是回答效率问题,因为您已经解决了主要问题:

您可以使用 HashSet 更快地找到重复项。您必须知道“包含”方法在 HashSet 上的执行速度比在 ArrayList 上快得多:

public Collection<Vertex2D> duplicateVertices() {
    Set<Vertex2D> singleSet = new HashSet<Vertex2D>();
    List<Vertex2D> duplicated = new ArrayList<Vertex2D>();

    for (Vertex2D vertex : vertices.values()) {
        if (!singleSet.contains(vertex)) {
            singleSet.add(vertex);
        } else {
            duplicated.add(vertex);
        }
    }
    return duplicated;
}

另一个选择是使用 guava 的 HashMultiset。 “HashMultiset”与 HashSet 非常相似,但保留了出现次数的信息:

public Collection<Vertex2D> duplicateVertices() {
    HashMultiset<Vertex2D> multiset = HashMultiset.create(vertices.values());
    List<Vertex2D> duplicated = new ArrayList<Vertex2D>();

    for (Multiset.Entry<Vertex2D> entry : multiset.entrySet()) {
        if (entry.getCount() > 1) {
            duplicated.add(entry.getElement());
        }
    }
    return duplicated;
}

【讨论】:

    猜你喜欢
    • 2011-11-02
    • 1970-01-01
    • 1970-01-01
    • 2019-05-20
    • 1970-01-01
    • 2011-06-21
    • 1970-01-01
    • 1970-01-01
    • 2015-02-24
    相关资源
    最近更新 更多