ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

java – 如何区分Sorted集合中的两个equals对象?

2019-07-23 11:10:46  阅读:241  来源: 互联网

标签:java guava apache-commons


我可能错了,但对我来说,我们可以为一个对象重写equals,以便你认为它们有意义地等于.
映射中的所有条目都具有不同的键,并且集合中的所有条目都具有不同的值(不是有意义的等于)

但是当使用TreeMap或TreeSet时,您可以提供比较器.
我注意到,当提供比较器时,会绕过对象的equals方法,并且当比较器返回0时,两个objets被视为等于.
因此,我们有2个对象,但在地图键集或集合中,只保留一个.

我想知道是否有可能使用已排序的集合来区分两个不同的实例.

这是一个简单的示例:

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

请注意,使用新的String(“xxx”)会绕过String池的使用,因此s1!= s2.
我想知道如何实现比较器,使设置大小为2而不是1.

主要问题是:对于相同String值的两个不同实例,我如何在比较器中返回一些东西!= 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 }
  ...
}

它似乎工作正常,但自从比较(s1,s2)后规则不受尊重!= -compare(s2,s1)

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

编辑:对于那些想知道为什么我问这样的事情的人.好奇心比任何现实生活中的问题更重要.

但我已经处于这样的情况,虽然关于这个问题的解决方案:

想象一下你有:

class Label {
  String label;
}

对于每个标签,您都有一个关联的String值.
现在,如果您想要一个map,label->值,该怎么办?
但是现在如果你希望能够拥有两个与地图键相同的标签呢?
防爆
“label”(ref1) – >值1
“label”(ref2) – >值2
您可以实现equals,以便两个不同的Label实例不等于 – >我认为它适用于HashMap.

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

解决方法:

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

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

标签:java,guava,apache-commons
来源: https://codeday.me/bug/20190723/1513126.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有