gpt4 book ai didi

java - 如何区分排序集合中的两个相等对象?

转载 作者:塔克拉玛干 更新时间:2023-11-01 21:59:43 24 4
gpt4 key购买 nike

我可能是错的,但对我来说,我们可以覆盖一个对象的 equals,这样你就可以认为它们是有意义的 equals。映射中的所有条目都有不同的键,集合中的所有条目都有不同的值(不是有意义的等于)

但是当使用 TreeMap 或 TreeSet 时,您可以提供一个比较器。我注意到当提供比较器时,对象的 equals 方法被绕过,当比较器返回 0 时,两个对象被认为是相等的。因此,我们有 2 个对象,但在 map 键集或集合中,只保留了一个。

我想知道是否可以使用排序的集合来区分两个不同的实例。

这是一个简单的示例:

public static void main(String[] args) {
TreeSet<String> set = new TreeSet<String>();
String s1 = new String("toto");
String s2 = new String("toto");
System.out.println(s1 == s2);
set.add(s1);
set.add(s2);
System.out.println(set.size());
}

请注意,使用 new String("xxx") 会绕过字符串池的使用,因此 s1 != s2。我想知道如何实现一个比较器,以便设置大小为 2 而不是 1。

主要问题是:对于相同字符串值的两个不同实例,我如何在比较器中返回 != 0?

请注意,我想让比较器遵守规则:

Compares its two arguments for order. Returns a negative integer, zero, or a positive integer as the first argument is less than, equal to, or greater than the second. The implementor must ensure that sgn(compare(x, y)) == -sgn(compare(y, x)) for all x and y. (This implies that compare(x, y) must throw an exception if and only if compare(y, x) throws an exception.)

The implementor must also ensure that the relation is transitive: ((compare(x, y)>0) && (compare(y, z)>0)) implies compare(x, z)>0.

Finally, the implementer must ensure that compare(x, y)==0 implies that sgn(compare(x, z))==sgn(compare(y, z)) for all z.

It is generally the case, but not strictly required that (compare(x, y)==0) == (x.equals(y)). Generally speaking, any comparator that violates this condition should clearly indicate this fact. The recommended language is "Note: this comparator imposes orderings that are inconsistent with equals."

我可以使用这样的技巧:

public int compare(String s1,String s2) {
if s1.equals(s2) { return -1 }
...
}

它似乎工作正常,但由于 compare(s1,s2) != -compare(s2,s1) 而没有遵守规则

那么这个问题有什么优雅的解决方案吗?


编辑:对于那些想知道我为什么问这样的事情的人。与其说是现实生活中的问题,不如说是出于好奇。

但我已经遇到过这样的情况,虽然我正在考虑解决这个问题:

假设您有:

class Label {
String label;
}

对于每个标签,您都有一个关联的字符串值。现在如果你想要一个 map ,label->value 怎么办。但是现在,如果您希望能够拥有与 map 键相同的标签两倍怎么办?前任“标签”(ref1)-> value1“标签”(ref2)-> value2您可以实现 equals,以便两个不同的 Label 实例不相等 -> 我认为它适用于 HashMap。

但是如果您希望能够按字母顺序对这些 Label 对象进行排序怎么办?您需要提供比较器或实现可比性。但是,我们如何区分具有相同标签的 2 个标签的顺序呢?我们必须!compare(ref1,ref2) 不能返回 0。但它应该返回 -1 还是 1?我们可以比较内存地址或类似的东西来做出这样的决定,但我认为这在 Java 中是不可能的......

最佳答案

如果您使用的是 Guava,则可以使用 Ordering.arbitrary() ,这将对在 VM 的生命周期内保持一致的元素施加额外的顺序。您可以使用它以一致的方式打破 Comparator 中的关系。

但是您可能使用了错误的数据结构。您是否考虑过使用允许添加多个实例的Multiset(例如TreeMultiset)?

关于java - 如何区分排序集合中的两个相等对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10315850/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com