精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (11)
|
|
---|---|
作者 | 正文 |
发表时间:2012-03-02
HashSet ,作为Set集合的一个实现类,很多书中写到Set中不能存放重复的元素。事实上并非如此。看下面的一个简短的例子 import java.util.*; class AddObject { int hashCode; public AddObject(int hashCode) { this.hashCode = hashCode; } public int hashCode() { return hashCode; } } public class TestHashSet { public static void main(String args[]) { // set在存储数据时需要遍历之前所存放的数据(hashCode与内存地址),用于与当前所要添加的元素进行对比。若得出结果相等, // 则不添加。比较的方法是:首先比较两个对象的hashCode,如果不相等,则直接添加;否则,再用equals()(比较地址) // 方法进行比较,如果结果返回为true,则不添加;否则,添加 Set<AddObject> set = new HashSet<AddObject>(); // 设置初始hashCode值 AddObject ao = new AddObject(2); // 第一次添加 set.add(ao); // 重新设置hashCode ao.hashCode = 3; // 再次添加 set.add(ao); System.out.println(set.size()); // 输出结果显然是2。但两次添加的对象显然是同一个对象,所以Set中不能存放重复的元素这一说法是不完善的 } } TreeSet:一个有序的Set(一般为升序)·,它是通过compareTo()这个函数来判断所添加的数据是否已经存在和排序 import java.util.*; class A implements Comparable { public int compareTo(Object o) { // 返回值为0时,表示两个对象相等不可以添加;否则添加成功 return 1; } } public class TestTreeSet { public static void main(String[] args) { TreeSet<A> ts = new TreeSet<A>(); A a = new A(); A b = new A(); // 进行添加时,调用compareTo()方法进行比较。一来判断是否重复;二来,是为了排序 ts.add(a); ts.add(b); System.out.println(ts.size()); } }
声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2012-03-03
楼主回去看看effective java吧
|
|
返回顶楼 | |
发表时间:2012-03-03
HashSet 内部使用HashMap来存,而HashMap 判断是否重复的条件是:
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))) |
|
返回顶楼 | |
发表时间:2012-03-04
jht5945 写道 楼主回去看看effective java吧
这个,看《think in java》也可以了。 最好的方式是 www.google.com : HashMap, TreeSet. 我当年就这么学的 |
|
返回顶楼 | |
发表时间:2012-03-04
看下HashSet源码就行了 构造函数第一句话 new HashMap()
|
|
返回顶楼 | |
发表时间:2012-03-04
难道lz真的不知道equals和hashCode这两个方法是什么关系?
|
|
返回顶楼 | |
发表时间:2012-03-04
源码已看过。但我得到结论也并非不对,已实际验证过了。
|
|
返回顶楼 | |
发表时间:2012-03-05
最后修改:2012-03-05
楼主的想法挺有意思的.
但是你破坏了object常规协定,也就难怪集合类无法正常工作了 引用 在 Java 应用程序执行期间,在对同一对象多次调用 hashCode 方法时,必须一致地返回相同的整数,前提是将对象进行 equals 比较时所用的信息没有被修改。
如果根据 equals(Object) 方法,两个对象是相等的,那么对这两个对象中的每个对象调用 hashCode 方法都必须生成相同的整数结果。 |
|
返回顶楼 | |
发表时间:2012-03-05
lz肯专研的意识很好。 大家现在既然都告诉你你的方式错了,你就回头好好再看看吧。
|
|
返回顶楼 | |
发表时间:2012-03-05
为了优化,hashset会缓存hash值,你更改了hash值后不会重新计算hash值,所以就放到了不同的桶中。在有些大的对象中,由于hash的计算比较复杂,所以hash的开销是很大的
|
|
返回顶楼 | |