2010-11-20 74 views
2

我知道一個java treeset不能有相同的元素,所以我必須以某種方式區分一個元素,即使它們具有相同的「值」。我希望能夠排列元素,並且我注意到一個有趣的行爲。TreeSet中的排名元素

TreeSet<Integer> set = new TreeSet<Integer>(new Comparator<Integer>() 
     { 
      public int compare(Integer arg0, Integer arg1) 
      { 
       if(arg0 > arg1) 
        return -1; 
       return 1; 
      } 
     }); 

     set.add(40); 
      set.add(20); 
     set.add(30); 
      set.add(20); 

     for(Integer i:set) 
     { 
      System.out.println("Rank: "+(set.headSet(i,false).size()+1)+" Number: "+i); 
     } 

這是輸出:

Rank: 1 Number: 40 
Rank: 3 Number: 30 
Rank: 5 Number: 20 
Rank: 5 Number: 20 

這是耳機是應該做的:

Returns a view of the portion of this set whose elements are less than (or equal to, if inclusive is true) toElement. The returned set is backed by this set, so changes in the returned set are reflected in this set, and vice-versa. The returned set supports all optional set operations that this set supports. 

我在按降序排序,所以我認爲它應該做的對面。第一個元素沒有比它大,所以它返回0,然後我加1來得到它的等級。第二個元素有一個比它大的東西,所以我認爲它應該返回1,加1就是2.這很奇怪。我想我犯了一個簡單的錯誤。我還需要弄清楚如何處理這兩個20年代。我希望他們的排名都是3,但是treeset認爲他們是不同的數字。我想我可以使用TreeMultiSet或其他第三方庫。

回答

0

我想我可以使用TreeMultiSet或其他第三方庫。

既然你違反的一組的基本特徵之一,我說你不應該一個SetTreeSet,至少直接使用。選項:

  • 使用List(並保持與排序Collections.sort()和Collections.binarySearch())
  • 使用IdentityHashMap,只使用該值作爲鍵映射到自身
  • 使用一個TreeMap和值映射到OCCURENCES的#(提取物的清單和排序需要的話)
  • 使用第三方庫(袋或者多集)
  • 實現自己的包/多集

因爲我對編程上下文了解不多,所以很難提出具體的解決方案,但希望能夠提出一些其他想法。

+0

這是一個很好的觀點。我可以嘗試使用常規列表並保持排序 – JPC 2010-11-21 00:10:16

2

兩個20是一個問題,因爲你的比較實施違反the contract

實現程序必須確保SGN(則x.compareTo(Y))== -sgn(y.compareTo(X))的所有x和y。

如果x = 20和y = 20,這是不是真的在你的實行:1 == - (1)

您可以通過返回0解決這個問題,如果arg0.equals(ARG1) 。

注意:對於Integer類的對象,您需要使用「equals」而不是「==」。

+0

如果它們相等,我不能返回0,因爲我仍然需要它們在集合中。 – JPC 2010-11-21 00:08:23

+0

如果你想要多個相同的條目,那麼你應該使用一個List而不是濫用Set。 Collections.sort()將爲您排序。 – 2010-11-21 08:55:38