【问题标题】:Ranking elements in TreeSet对 TreeSet 中的元素进行排名
【发布时间】:2010-11-20 20:19:59
【问题描述】:

我知道 java 树集不能有相同的元素,所以我必须以某种方式将一个元素与另一个元素区分开来,即使它们具有相同的“值”。我希望能够对元素进行排名,并且注意到一个有趣的行为。

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,但树集认为他们是不同的数字。我想我可以使用 TreeMultiSet 或其他一些第三方库。

【问题讨论】:

    标签: java sorting collections treeset


    【解决方案1】:

    这两个 20 是一个问题,因为您的比较实现违反了the contract

    实施者必须确保所有 x 和 y 的 sgn(x.compareTo(y)) == -sgn(y.compareTo(x))。

    如果 x=20 和 y=20,则在您的实现中不是这样:1 == -(1)

    如果 arg0.equals(arg1),您可以通过返回 0 来解决此问题。

    注意:对于 Integer 类的对象,您需要使用“等于”而不是“==”。

    【讨论】:

    • 如果它们相等,我不能返回 0,因为我仍然需要它们在集合中。
    • 如果你想要多个相等的条目,那么你应该使用 List 而不是滥用 Set。 Collections.sort() 会为你排序。
    【解决方案2】:

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

    由于您违反了集合的基本特征之一,我想说您不应该使用SetTreeSet,至少直接使用。选项:

    • 使用List(并使用 Collections.sort() 和 Collections.binarySearch() 对其进行排序)
    • 使用 IdentityHashMap 并仅使用值作为映射到自身的键
    • 使用 TreeMap 并将值映射到出现次数(提取到列表并根据需要进行排序)
    • 使用第 3 方库(Bag 或 MultiSet)
    • 实现您自己的包/多组

    由于我对编程上下文了解的不多,因此很难提出具体的解决方案,但希望这会带来一些其他的想法来考虑。

    【讨论】:

    • 这很好。我可以尝试使用常规列表并保持排序
    猜你喜欢
    • 2011-06-22
    • 1970-01-01
    • 2017-10-05
    • 1970-01-01
    • 2019-04-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多