如果这是一个愚蠢的问题(特别是对于用 java 开发超过 4 年的人)或者它是否已得到解答(我已经搜索了堆栈溢出,尽管问题很简单,但我找不到重复),但我创建了两个优先级队列,并想检查它们是否以完全相同的顺序包含完全相同的元素。然而,当我在两个看似相同优先级的队列上调用 .equals() 时,我返回了 false。我希望通过直接比较(==)而不是通过 .equals() 方法得到这么多。我查看了 java 文档,但他们没有对此行为提供解释。
为了测试此行为,我运行了以下代码段:
PriorityQueue<Character> window = new PriorityQueue<>();
PriorityQueue<Character> base = new PriorityQueue<>();
System.out.println(window.equals(base));
System.out.println(base.equals(base));
window.offer('a');
window.offer('b');
base.offer('a');
base.offer('b');
System.out.println(window.equals(base));
Run Code Online (Sandbox Code Playgroud)
输出是:
false
true
false
Run Code Online (Sandbox Code Playgroud)
然而,我期望的是:
true
true
true
Run Code Online (Sandbox Code Playgroud)
我之前已经重写了 equals 方法,所以如果这是我必须做的事情,我可以处理它,但我只是对结果感到非常惊讶。我知道我可以将 PriorityQueue 转换为字符串或数组,然后比较它们,但这违背了使用 PriorityQueue 的全部意义(更不用说它会占用的所有多余空间)。
我在 HashMap 的上下文中读过某处:
hashCode() allows sorting objects by their hash values, and then the Object#equals method only needs to be invoked when objects share the same hash value.
是否意味着最终调用 equals() 方法时,已经比较了 hashCode 并发现必然相等?这种情况有什么例外吗?
问题的第二部分:在 equals() 方法中检查两个对象的 hashCode() 是否有意义?
public boolean equals(Object obj) {
if (obj == this) {
return true;
}
if (obj == null) {
return false;
}
if (!(obj instanceof InternalObjectSerialized)) {
return false;
}
InternalObjectSerialized<?> inputObj = (InternalObjectSerialized<?>) obj;
if (!(Arrays.equals(this.bytes, inputObj.bytes))) {
return false;
}
// …Run Code Online (Sandbox Code Playgroud) 由于我没有任何很好的数学技能,我问你是否有任何算法我应该用于一个可能在将来改变的课程.
考虑以下场景:
"角色"类包含以下字段:
private boolean admin;
private boolean printer;
Run Code Online (Sandbox Code Playgroud)
几个星期后,我决定添加一个角色"客人":
private boolean admin;
private boolean printer;
private boolean guest;
Run Code Online (Sandbox Code Playgroud)
几周后我决定删除角色"打印机";
private boolean admin;
private boolean guest;
Run Code Online (Sandbox Code Playgroud)
由于我将在数据库中保留哈希码,因此我必须100%确定此类的所有版本都生成唯一的哈希码.
也许这不是问题,我一直使用Eclispe IDE源代码生成器中提供的那个.
你能告诉我,如果我对Eclipse IDE(Indigo)Java版本> = 6方法安全,或者给我一些关于这个主题的其他建议.我相信这是一件很平常的事情.
提前致谢
我理解在类中重写hashcode和equals的基本概念,但是任何人都可以给我一个例子(代码),其中equals将失败只因为hashcode没有被覆盖?提前致谢.
我正在学习Overriding hashCode()和课堂equals(Object obj)方法Object.
类中的equals(Object obj)方法体Object是:
public boolean equals(Object obj) {
return (this == obj);
}
Run Code Online (Sandbox Code Playgroud)
并hashCode()是native:
public native int hashCode();
Run Code Online (Sandbox Code Playgroud)
我有一个类Test有overrided equals(Object obj)和hashCoe():
public class Test {
public static void main(String[] args){
Test t1 = new Test();
Test t2 = new Test();
System.out.println("t1 toString() : " + t1.toString());
System.out.println("t1, Hex value of hashcode : " + Integer.toHexString(t1.hashCode()));
System.out.println("t2 toString() : " + …Run Code Online (Sandbox Code Playgroud) class Rational {
int num = 0;
int denom = 0;
public Rational(int num, int denom) {
this.num = num;
this.denom = denom;
}
public static void main(String[] args) {
Rational r1 = s.new Rational(1, 1);
Rational r2 = s.new Rational(1, 1);
System.out.println(r1.hashCode());
System.out.println(r2.hashCode());
Run Code Online (Sandbox Code Playgroud)
}
我有两个相同的对象,但是它们具有不同的hashCode。这是为什么?我尝试覆盖Rational中的.equal方法,因此r1.equals(r2)== true。但是它们仍然产生不同的Java hashCode。
我有一个对象集合,我希望从这个对象集合中生成一个哈希值(使用SHA256).
这些散列这些对象的过程是零知识证明系统的一部分,其中证明者生成证明,该证明稍后由验证者验证.这个证明实际上是哈希函数的输出.
这些对象都包含3或4个大的BigInteger值(大小为2048位).对象的数量是可变的,但它将在4到10之间.
我编写了以下方法,用于从可变数量的对象生成哈希值:
public byte[] buildHashFromHashcodes(final Object... listOfObjects) {
for (Object obj : listOfObjects) {
if (obj == null) {
throw new Exception(
"Input objects cannot be null");
}
_md.update(intToBytes(obj.hashCode()));
}
return _md.digest();
}
private byte[] intToBytes(final int intValue) {
return new byte[] {(byte) (intValue >> 24),
(byte) (intValue >> 16), (byte) (intValue >> 8),
(byte) intValue };
}
Run Code Online (Sandbox Code Playgroud)
我的问题与在此代码中使用hashCode方法有关.具体来说,我试图确定hashCode方法的使用是否会削弱系统的安全性,因为它只生成一个32位数,因此只在每次迭代期间使用32位信息更新散列.因此,我不确定此过程中此信息的丢失是否真的会削弱系统.
这些对象的hashCode方法的实现使用大的BigInteger值来生成它们的哈希码,但是在返回之前该数字被截断为int.
我担心的部分原因是,某些对象的哈希码之间可能存在冲突.但话说回来,哈希在循环内部被多次更新,因此单个冲突不会是一个大问题.
让我们假设对象集合中有4个对象.在循环的第一次迭代中,将使用32位来更新散列,在第二次迭代中,将使用另外32位来更新散列,等等.
据我所知,在调用update方法之后执行散列算法.不是128位(4个对象)将存储在缓冲区中,然后使用这128位作为输入执行散列算法.
因此,我们可以说在最终更新之后哈希所处的状态总数将是(2 ^ 32)*(2 ^ 32)*(2 ^ 32)*(2 ^ 32)?(在实践中,这当然不会发生,因为它会在某些时候被截断).
我相信使用hashCode是一种安全的方法,因为在每次迭代期间都会调用update方法.
为了避免对象之间发生冲突的风险,另一种方法是使用每个对象的toString()方法,该方法返回一个包含每个对象的全部熵的String(大BigInteger数字的值包含在字符串).这意味着在循环的每次迭代期间使用更多信息更新散列,但我不确定是否有必要.
所以,我的问题是,在这段代码中使用hashCode方法会削弱系统的强度吗?
我理解equals和hashCode方法之间的契约.如果equals被覆盖,hashCode也应该是.我可以覆盖hashCode方法以始终返回相同的值,比如int 23吗?我可以覆盖hashCode每次调用时返回随机数的方法吗?
假设我要创建一个HashSet或,HashMap其键是原始类型的数组,如下所示:
Set<int[]> setOfIntArrays = new HashSet<>();
Map<char[], String> mapOfCharArrays = new HashMap<>();
Run Code Online (Sandbox Code Playgroud)
这些结构将对数组使用哪些哈希码?
我知道根类Object包含hashCode(),因此它可用于任何继承类的实例(在其中可以重写或不重写)。本Arrays类有一堆的静态hashCode(...)所有基本类型数组的方法。这些方法是否也作为“原始”类型数组的(重写)实例方法“内置”?由于数组在集合和映射中充当普通类,因此这样做似乎合乎逻辑。但是,没有用于类的javadoc,int[]并且JLS中的“数组”一章也无法阐明这种情况。