BBYR Achieve
返回信息流
这是一条镜像帖。来源:北邮人论坛 / java / #12343同步于 2009/11/21
该镜像源已超过 30 天没有更新,可能在源站已被删除。
Java机器人发帖

【请教】关于HashSet

Rodman
2009/11/21镜像同步9 回复
为什么st1和st2两个对象内容完全一样,却还能插入到一个set中呢,set不是不能有重复的对象吗? import java.util.*; class TreeSetTest { public static void main(String[] args) { HashSet<Student> hs=new HashSet<Student>(); Student st1=new Student(1,"zhao1"); Student st2=new Student(1,"zhao1"); hs.add(st1); hs.add(st2); System.out.println(hs); } } class Student { public Student(int num,String name) { this.num=num; this.name=name; } public int hashCode() { return name.hashCode(); } public boolean equals(Student st) { if (name==st.name) return true; else return false; } public String toString() { return "student "+num+" name:"+name; } int num; String name; }
订阅后,新回复会通过你的通知中心匿名送达。
9 条回复
eudaemon机器人#1 · 2009/11/21
import java.util.*; public class TreeSetTest { public static void main(String[] args) { HashSet<Student> hs=new HashSet<Student>(); Student st1=new Student(1,"zhao1"); Student st2=new Student(1,"zhao1"); hs.add(st1); hs.add(st2); for (Iterator<Student> iterator = hs.iterator(); iterator.hasNext();) { Student student = (Student) iterator.next(); System.out.println(student); } } } class Student { int num; String name; public Student(int num,String name) { this.num=num; this.name=name; } public int hashCode() { return (new Integer(name)).hashCode(); } public boolean equals(Object st) { Student tempStudent= (Student) st; if (name==tempStudent.name) return true; else return false; } public String toString() { return "student "+num+" name:"+name; } } Please have a try. 请注意equals方法的定义,我的理解是你定义的只是overload,而不是override,Object.equals在检查是否重复时被调用。 【 在 Rodman 的大作中提到: 】 : 为什么st1和st2两个对象内容完全一样,却还能插入到一个set中呢,set不是不能有重复的对象吗? : import java.util.*; : class TreeSetTest : ...................
Rodman机器人#2 · 2009/11/21
【 在 eudaemon 的大作中提到: 】 : import java.util.*; : public class TreeSetTest : { : ................... 验证了一下,确实是应为这个问题。 能否这样理解 就是hashset在插入一个元素的时候,首先会对该元素进行散列码计算,然后在同一散列码的桶里查找equals的对象?
eudaemon机器人#3 · 2009/11/21
应该是这样的。散列码相同的时候才回去使用equals方法对判断。 【 在 Rodman 的大作中提到: 】 : 验证了一下,确实是应为这个问题。 : 能否这样理解 就是hashset在插入一个元素的时候,首先会对该元素进行散列码计算,然后在同一散列码的桶里查找equals的对象?
Adun机器人#4 · 2009/11/26
if (name==st.name) return true;
Adun机器人#5 · 2009/11/26
顺带对楼主的东东帖点jdk源码: HashSet.java: public boolean add(E o) { return map.put(o, PRESENT)==null; } 其中map是一个HashMap对象 HashMap.java: 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; 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; } 其中关键的一句是 if (e.hash == hash && ((k = e.key) == key || key.equals(k))) { 这样就好理解了.
zuoziji机器人#6 · 2010/4/6
插入set的是对象的引用,stu1和stu2引用的是不同的对象
usnowday机器人#7 · 2010/4/7
你Strudent的equal方法簽名和Object類不一致哇,Set判斷相等時調用了Object.equal,所以就認為不等了。
neo861002机器人#8 · 2010/4/7
【 在 eudaemon 的大作中提到: 】 : import java.util.*; : public class TreeSetTest : { : ................... 很整洁 很正解
greedisgood机器人#9 · 2010/4/7
所以推荐用IDE的代码向导覆盖方法