对 TreeSet 中的元素进行排名

发布于 2024-10-03 08:45:44 字数 1316 浏览 4 评论 0原文

我知道 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 或其他一些第三方库。

I know a java treeset can't have identical elements and so I have to somehow differentiate an element from another even if they have the same "value". I want to be able to rank the elements and I'm noticing an interesting behavior.

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

And this is the output:

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

This is what headset is supposed to do:

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. 

I'm sorting in descending order so I think it should do the opposite. The first element has nothing greater than it, so it returns 0, and then I add 1 to get its rank. The second element has one thing larger than it, so I think it should return 1, adding 1 makes 2. That's kind of weird. I think I'm making a simple mistake. I also need to figure out how to deal with the two 20's. I want their rank to both be 3 but the treeset thinks they're different numbers. I suppose I could use TreeMultiSet or some other third party library.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

末骤雨初歇 2024-10-10 08:45:44

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

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

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

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

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

The two 20 are an issue because your implementation of compare violate the contract:

The implementor must ensure sgn(x.compareTo(y)) == -sgn(y.compareTo(x)) for all x and y.

if x=20 and y=20, this is not true in your implemenation: 1 == -(1)

You can fix this issue by returning 0, if arg0.equals(arg1).

Note: You need to use "equals" instead of "==" for objects of class Integer.

遇见了你 2024-10-10 08:45:44

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

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

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

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

I suppose I could use TreeMultiSet or some other third party library.

Since you're violating one of the basic characteristics of a set, I'd say you shouldn't use a Set or TreeSet, at least directly. Options:

  • use a List (and keep it sorted with Collections.sort() and Collections.binarySearch())
  • use an IdentityHashMap and just use the value as the key mapped to itself
  • use a TreeMap and map the value to # of occurences (extract to a list and sort as needed)
  • use a 3rd party library (Bag or MultiSet)
  • implement your own bag/multiset

Since I don't know more about the programming context, its hard to suggest a specific solution, but hopefully this brings up some other ideas to consider.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文