2014-12-06 29 views
-1

我試圖搜索論壇的答案,但我找不到解決我的問題。我有代表多邊形的TreeMap。我的第一個任務是返回具有特定值的元素的鍵,第二個任務是返回所有重複的頂點。這裏是我的代碼和方法,我試圖執行:JAVA在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; 
} 

我感謝每一個幫助!

+0

你能告訴我們什麼是不準確的工作,你有什麼期待和您能得到什麼?當你打電話給「addVertex」時,也很高興知道你把「label」放在哪裏:它們是否是唯一值?此外,當你寫「if(entry.getValue()== vert)」你真的是指「==」,而不是「.equals()」?這第一個是對象引用比較,第二個是對象相等。 – Joel 2014-12-06 14:01:54

+0

除了您遇到的問題,您的實施效率不高。您不應該在所有頂點上循環兩次(平方)以找到重複項。這是o(n²)複雜性,而你可以有o(n)。但這是另一個問題 – Joel 2014-12-06 14:02:11

+0

是的,我意識到我的描述不對。 Equals()是問題,我不是很好的程序員:D(順便說一句,我不知道如何使方法duplicateVertices更有效率,我很欣賞任何想法) – mato 2014-12-06 17:14:04

回答

0

如何創建第二TreeMap的或HashMap的

HashMap<Vertex2D, ArrayList<String>> 

然後遍歷在你上面的例子,併爲每個元素的第一TreeMap中檢查是否已經有了它,如果是一個條目,只需添加鍵入此條目列表的字符串。

最後你遍歷這個映射並檢查每個條目列表是否有多個條目,如果是這種情況你有一個副本(並做任何你想做的事情)。

可能有更好的性能的其他方式,但這種方式將工作。

有一個similar topic here

+0

我終於發現爲什麼我的代碼不工作。問題是我在這兩種方法中都使用==方程。我應該使用我在Vertex2D類中實現的equals()。愚蠢的我:D – mato 2014-12-06 16:35:36

+0

哦,好的,在這種情況下使用你的版本。 :) – Phiwa 2014-12-06 16:49:59

0

只是回答了效率問題,因爲你已經解決了你的主要問題:

您可以更快地找到重複使用的HashSet。你必須知道的方法「包含」比ArrayList的執行上的HashSet要快得多:

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; 
} 

另一種選擇是使用番石榴的HashMultiset。 A「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; 
}