当前位置: 首页 > 知识库问答 >
问题:

实现Java对象标识的比较器[duplicate]

傅皓君
2023-03-14

我有一个使用对象标识的令牌类(如equals只返回TokenA==TokenB)。我想在TreeSet中使用它。这意味着我需要实现与引用相等兼容的两个令牌之间的比较。我不关心具体的实现,只要它与equals一致并履行契约(根据TreeSet:"注意,如果要正确实现Set接口,由set维护的顺序(无论是否提供显式比较器)必须与equals一致。")

注意:这些令牌是在多个线程上创建的,可以在不同的线程上进行比较。

这样做的最佳方法是什么?

我尝试过的想法:

  • 使用系统。identityHashCode——问题在于,不能保证两个不同的对象总是有不同的hashcode。由于生日悖论,在两个令牌发生碰撞之前,您只需要大约77k个令牌(假设System.identityHashCode均匀分布在整个32位范围内,这可能不是真的…)

顺便说一下,我不能简单地把问题抛在一边,假设唯一的对象有唯一的哈希代码。这就是我正在做的,但是比较器中触发了断言,所以我深入研究了一下,瞧,在我的机器上,如下所示:

import java.util.*;
import java.util.Collections.*;
import java.lang.*;

public class size {
    public static void main(String[] args) {
        Map<Integer, Integer> soFar = new HashMap<>();
        for (int i = 1; i <= 1_000_000; i++) {
            TokenA t = new TokenA();
            int ihc = System.identityHashCode(t);
            if (soFar.containsKey(ihc)) {
                System.out.println("Collision: " + ihc +" @ object #" + soFar.get(ihc) + " & " + i);
                break;
            }
            soFar.put(ihc, i);
        }
    }
}
class TokenA {

}

印刷品

Collision: 2134400190 @ object #62355 & 105842

所以碰撞确实存在。有什么建议吗?

共有1个答案

殷耀
2023-03-14

这里是问题tokenA==tokenB比较身份,tokenA。equals(tokenB)比较中定义的内容。无论身份如何,该类的equals()

因此,两个对象可以具有. equals()返回true而不是相同的对象实例,它们甚至不必具有相同的类型或共享超级类型。

实现comareTo()是任何你想比较的对象的属性。你只需要编写代码,让它做你想做的,但是comareTo()可能不是你想要的。comareTo()是为了比较,如果你两个东西不是

public boolean equals(Object o)
{
    return this == o;
}

 类似资料:
  • 我正在尝试编写一个使用最小优先级队列的算法,所以我在谷歌上四处查看并找到了PriorityQueue。不过,似乎为了使用它,我需要告诉它我希望它如何排列优先级,并且这样做的方法是使用比较器(我想比较我的“Node1”对象的特定数据字段)。更多的谷歌搜索提出了创建一个新的比较器的想法,它实现了比较器但覆盖了比较方法。我正在尝试的是这样(以及它的其他变体): 编译器有几个理由提出抗议,其中之一是我没有

  • 我正在尝试创建一个二进制搜索程序,该程序可以使用各种类型的变量(int、float、string等)来查看数组中是否存在元素。我正试图找出如何比较变量。下面是我正在使用的内容的草图: 我甚至不确定使用对象是否是最好的方法。

  • 我知道这些接口用于对集合中的对象进行排序。但我怀疑这两者的真正区别。我读到的一个事实是,如果要比较两个对象而不使用当前对象,请使用Compariable(此)。 但我的问题是即使使用比较器,我们也会比较相同的对象类型。 这里真正的区别是什么。我很困惑。假设下面的例子, 如果我使用比较器,我会让一个类实现比较器,而不是这个。年龄,它有人。年龄那么这里有什么不同呢? 我不知道Collections.s

  • 我在理解和使用比较器方面有一个问题,有人问我以下问题: 我在一个单独的Employee类中使用compareTo比较器接口来调用比较器对象的重载使用。 任何帮助,建议,代码行将非常感谢!!

  • 问题内容: 我需要编写一个比较器,它采用类型A的对象A和类型B的对象B。这两个对象不是公共对象的扩展。它们的确不同,但是我需要通过其中的通用字段来比较这两个对象。我必须使用比较器接口,因为对象存储在Set中,并且在必须对CollectionUtils执行操作之后。我在Google上搜索了一下,发现了Comparator的解决方案,但只有相同的类型。 我试图朝这个方向实施思考,但是我不知道我是否在正

  • 我需要写一个比较器,取一个a类型的对象a和一个B类型的对象B。这两个对象不是一个公共对象的扩展。他们确实是不同的,但我需要比较这两个对象在它的共同领域。我必须使用比较器接口,因为对象存储在Set中,之后我必须使用CollectionUtils进行操作。我搜索了一点点,我用比较器找到了解决方案,但只有相同的类型。 TXS 附注:我在不同的集合中添加两个对象: 之后我会这样想: