HashSet<E>
泛型E必须重写hashCode方法,否则会导致add结果与预期不符
如
class NewClass{ String s; public NewClass(String s){ this.s=s; } @override public int hashCode(){
//此处返回字符串s的hashCode() return s.hashCode(); } } NewClass n = new NewClass("1"); NewClass n1 = new NewClass("1"); Set<NewClass> set= new Set<>(); set.add(n); set.add(n1); sout(set.size());
若不重写hashCode()则输出为2,若重写hashCode()则输出为1。为什么会这样?
查看HashSet的的源码会发现,HashSet的Contains方法,和add方法,其实是引用了HashMap的containskey()和put()方法。
而这HashMap的这两个方法都用到了泛型类的hashCode()
连个方法中的hash()方法代码如下:
返回值都和泛型E.hashCode()有关,所以当自建类作为泛型类生成HashSet和HashMap时需要重写自建类的hashCode()。
如果hashCode()没有重写,则调用的是java.lang.Object的hashCode()
刚看到这行代码的时候是懵逼的,没有方法体,这不是抽象类吗?然后百度了native修饰符,发现这篇文章写得很清楚https://www.cnblogs.com/Qian123/p/5702574.html,native是于其他语言(如C++)联合开发是使用的,也就是说hashCode()方法的方法体是其他语言实现的,具体调用时由JNI(java native interface)调用其他语言生成的库文件,如dll文件。