intro
Java中的集合有两类,一类是List,另一类是set。前者是有序的,元素可重复;后者是无序的,元素不可重复。
判断集合中的元素是否重复
当新加入一个元素中,首先会在集合中遍历是否存在旧元素和新元素值相等,即用equal()函数。
public boolean equals(Object obj){
return (this == obj);
}
很明显是对两个对象的地址值进行的比较(即比较引用是否相同)。但是我们必需清楚,当String、Math、还有Integer、Double。。。。等这些封装类在使用equals()方法时,已经覆盖了object类的equals()方法。比 如在String类中如下:
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String)anObject;
int n = count;
if (n == anotherString.count) {
char v1[] = value;
char v2[] = anotherString.value;
int i = offset;
int j = anotherString.offset;
while (n-- != 0) {
if (v1[i++] != v2[j++])
return false;
}
return true;
}
}
return false;
}
如果从成千上万个元素间遍历,会影响速度。所以有人发明了一种哈希算法来提高从集合中查找元素的效率。
哈希算法
哈希算法将集合分成若干个存储区域,每个对象可以计算出一个哈希码,可以将哈希码分组,每组分别对应某个存储区域,根据一个对象的哈希码就可以确定该对象应该存储的那个区域。
hashCode()输入对象的内存地址,而返回哈希码。这样一来,当集合要添加新的元素时,先调用这个元素的hashCode(),就能一下子定位到它应该放置的物理地址上。如果这个位置上没有元素,它就应该直接储存在这个位置上,不用再进行比较了。如果这个位置上已有元素了,就调用它的equal()方法进行比较。
比如String中的hashCode():
public int hashCode() {
int h = hash;
if (h == 0) {
int off = offset;
char val[] = value;
int len = count;
for (int i = 0; i < len; i++) {
h = 31*h + val[off++];
}
hash = h;
}
return h;
}
Reference
[1] https://www.cnblogs.com/yuyu666/p/9733572.html