当我运行此代码时,为什么我的实现对两个条目都生成相同的代码,为什么不只hashCode()
调用equals
方法呢?hashCode()``hashCode``HashSet
import java.util.HashSet;
public class Test1 {
public static void main(String[] args) {
Student st=new Student(89);
HashSet st1=new HashSet();
st1.add(st);
st1.add(st);
System.out.println("Ho size="+st1.size());
}
}
class Student{
private int name;
private int ID;
public Student(int iD) {
super();
this.ID = iD;
}
@Override
public int hashCode() {
System.out.println("Hello-hashcode");
return ID;
}
@Override
public boolean equals(Object obj) {
System.out.println("Hello-equals");
if(obj instanceof Student){
if(this.ID==((Student)obj).ID){
return true;
}
else{
return false;
}
}
return false;
}
}
输出为:
Hello-hashcode
Hello-hashcode
Ho size=1
哈希集首先检查引用相等性,如果通过,则跳过该.equals
调用。这是一个优化和工作,因为合同equals
,如果指定a == b
然后a.equals(b)
。
我在下面附加了源代码,并突出显示了此检查。
相反,如果添加两个不相同引用的相等元素,则会获得预期的效果:
HashSet st1=new HashSet();
st1.add(new Student(89));
st1.add(new Student(89));
System.out.println("Ho size="+st1.size());
结果是
$ java Test1
Hello-hashcode
Hello-hashcode
Hello-equals
Ho size=1
这是来自OpenJDK 7的源代码,其中指明了相等性优化(来自HashMap的基础实现HashMap):
public V put(K key, V value) {
if (key == null)
return putForNullKey(value);
int hash = hash(key.hashCode());
int i = indexFor(hash, table.length);
for (Entry<K,V> e = table[i]; e != null; e = e.next) {
Object k;
// v-- HERE
if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
V oldValue = e.value;
e.value = value;
e.recordAccess(this);
return oldValue;
}
}
modCount++;
addEntry(hash, key, value, i);
return null;
}
下面是产生散列集大小为3而不是2的代码 您可以看到这两个对象在输出中具有相同的代码,但被计算为不同的,并且产生的代码被计算为3 请协助我如何工作。
我的任务是实现一个蛮力算法来输出一些n的整数[1,2,…, n]的所有排列。但是,我似乎在将ArrayList对象添加到HashSet时遇到了一些问题: 我发现对“nextPer的连续调用确实找到了所有排列,但是我不明白当我将排列添加到HashSet“allPer的排列”时会发生什么。我在n=3的情况下运行时得到的输出是这样的: [[3, 2, 1, 1, 2, 1, 1, 3, 1, 2], [
问题内容: 例如,当我们向窗格添加新按钮时,我们需要编写以下代码: 为什么我们需要调用“ getChildren()”?它甚至做什么?我们为什么不能说: 我们将按钮添加到窗格中。我们不会将其添加到其子项中, 问题答案: 简短的答案就是“您必须那样做,因为这就是API的编写方式”。当然,您可能真正要问的是为什么要这样编写API。我认为这实际上是两个(相关的)问题。一种与方法名称有关,以及该方法的作用
问题内容: 决定将这些方法包含在java.lang.Object中的背后原因是什么?平等和哈希对于许多类没有意义。 建立两个接口将更加合乎逻辑: 例如,HashSet定义可能看起来像 这将防止出现一个常见的初学者错误-使用项目集而不实现equals / hashCode。 问题答案: 当我们实现一个接口时,我们注入(或接受)该接口定义的合同。 &是两个不同的合同。但是,如果我们仔细观察,就会发现它
问题内容: 据我了解,默认容量为10,并且当其超过10时,它将创建具有新容量的新对象,依此类推。 因此,出于好奇,我输入下面的程序来检查的对象: 根据上述情况,当我未将默认初始容量设置为10时,因此在添加第11个元素时,它将创建一个新对象并增加的容量。 当我打印对象的哈希码时,每次都会给出一个新值。 以下是o / p: 根据默认容量的概念,直到第10个元素之前,都应打印相同的内容,因为在此之前不需
我试图使用Java以编程方式从XSD文件生成JAXB类。我使用以下代码片段来实现这一点: 生成的类只包含字段的方法。但是,我还希望包括、和方法。如何在生成代码时做到这一点?