看如下程序 我感觉a1和a2是相等的(equals方法已经被覆盖) 但是HashSet添加时把“相同值”添加进去了 搞不懂为什么 求大神解释
import java.util.HashSet;class A { private int id; public A(int id) { this.id = id; } //若两A对象id相同则返回true @Override public boolean equals(Object obj) { if(obj instanceof A) return id == ((A) obj).id; return false; } @Override public String toString() { return id + ""; }}public class Confusion { public static void main(String[] args) { A a1 = new A(1); A a2 = new A(1); A a3 = new A(2); HashSet<A> a = new HashSet<A>(); a.add(a3); a.add(a2); a.add(a1); System.out.println(a); //我感觉结果应该是[1,2]或[2,1] 但是结果是[1,2,1] ???? }}
import java.util.HashSet;class A { private int id; public A(int id) { this.id = id; } //若两A对象id相同则返回true @Override public boolean equals(Object obj) { if(obj instanceof A) return id == ((A) obj).id; return false; } @Override public String toString() { return id + ""; }}public class Confusion { public static void main(String[] args) { A a1 = new A(1); A a2 = new A(1); A a3 = new A(2); HashSet<A> a = new HashSet<A>(); a.add(a3); a.add(a2); a.add(a1); System.out.println(a); //我感觉结果应该是[1,2]或[2,1] 但是结果是[1,2,1] ???? }}
this.id = id;
} @Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + id;
return result;
} @Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
A other = (A) obj;
if (id != other.id)
return false;
return true;
} @Override
public String toString() { return id + ""; }}public class Confusion { public static void main(String[] args) { A a1 = new A(1); A a2 = new A(1); A a3 = new A(2); HashSet<A> a = new HashSet<A>(); a.add(a3); a.add(a2); a.add(a1);
System.out.println(a1.equals(a2));
System.out.println(a); }}还要重写下hashcode才行
在set类型的集合中,如何判断元素是否重复呢,这就需要使用Object.equals方法,但如果元素很多了,添加一个新元素时,比较的次数 就很多,例如已经有100个元素了,添加第101个元素时,就要和前面的元素比较100次,效率很低。 JAVA中采用哈希表的原理,哈希算法也称为散列算法,是将数据依据算法直接指定到一个地址上, hascode实际上是返回的对象存储的物理地址 HashSet类按照哈希算法来存取对象,当向集合中加入一个新对象时,会调用对象的HashCode()方法得到对象的哈希码,然后根据这个码计算出对象在集合中存储的位置。 Object类中定义了hashCode()和equals(Object o)方法,如果object1.equals(object2),那么说明这两个引用变量指向同一个对象,那么object1 and object2的hashCode也一定相等 为了保证HashSet能正常工作,要求当两个对象用equals比较相等时,hashCode也要相等,否则就会有可能加入两个相同的项。
return map.put(e, PRESENT)==null;
}HashMap的put方法:public V put(K key, V value) {
if (key == null)
return putForNullKey(value);
int hash = hash(key.hashCode());//使用hashCode来找存放位置,楼主没有改写hashCode方法所以原来值没有被覆盖掉。
int i = indexFor(hash, table.length);
for (Entry<K,V> e = table[i]; e != null; e = e.next) {
Object k;
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;
}Effective java中建议我们改写equals方法的时候一定要改写hashCode方法,否则在使用某些集合的时候会影响功能。
return语句少else吧