关于笔试题,我个人喜欢查看源码分析输出结果。有道笔试题,很多同学没有回答对。
考虑放弃这道题目,现在公布出来。
题目如下:
public class Bigram {
private final char first;
private final char second;
public Bigram(char first, char second) {
this.first = first;
this.second = second;
}
public boolean equals(Bigram b) {
return b.first == first && b.second == second;
}
public int hashCode() {
return 31 * first + second;
}
public static void main(String[] args) {
Set<Bigram> s = new HashSet<Bigram>();
for (int i = 0; i < 10; i++){
for (char ch = 'a'; ch <= 'z'; ch++){
s.add(new Bigram(ch, ch));
}
}
System.out.println(s.size());
}
}
这道题目输出260,而不是26。
这道题目是考查Java的对象相等还是全等。
判断对象相等,需要调用equals。判断全等需要调用==。
在覆盖equals方法时出错,函数接口应该是equals(Object b),代码中并没有调用基类的equals而是重载了。
而Object的equals方法是判断全等的,因此所有值都不同。
因此提倡在子类中覆盖积累的方法时,提倡标注方法为Override,编译器就能解决此类错误。
有的同学会认为是hashCode的问题,因为覆盖了Object的非final函数成员。
其实是没有问题的。在覆盖equals方法时,一定要覆盖hashCode,才能保证所有基于散列的集合中工作正常。
Java规范中约定:如果两个对象根据equals方法比较是相等的,那么调用两个对象中的hashCode方法,
必须产生相同的整数结果。