浏览 3507 次
锁定老帖子 主题:浅谈Hashtable与HashMap
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (1)
|
|
---|---|
作者 | 正文 |
发表时间:2009-02-26
最后修改:2010-01-08
提到hashtable,先要澄清两个问题hashCode与equals().Hashtable有容量和加载因子,容量相当于桶,因子相当于桶里的对象.而hashCode我们可以把它理解为桶的序号,所以HashCode相同的,即它们在同一个桶里,这两上对象就在同一个桶里,这时候如果他们还equals()的话,那么这两个对象就是一样的.而如果他们的hashCode不一样,即他们不在同一个桶里,那么这两个对象肯定是不一样的. 所以我们在用hashtable进行存储对象时要重写他们的hashCode与equals(),否则会出现很多重复的对象.
hashtable与hashMap最大的区别是,hashtable是方法同步的,而后者是异步的. 先来看看下面的例子吧:
public class Ball { private int size; private String name; public Ball(int size, String name) { this.size = size; this.name = name; } public void setSize(int size) { this.size = size; } public int getSize() { return size; } public void setName(String name) { this.name = name; } public String getName() { return name; } public static void main(String[] args) { Hashtable<Ball, String> hash = new Hashtable<Ball, String>(); hash.put(new Ball(1, "one"), "1"); hash.put(new Ball(2, "two"), "2"); hash.put(new Ball(1, "one"), "1"); System.out.println(hash.size()); } }
可能有的人会认为打印出出来的结果当然是2,有一个是重复的 但结果是3. 因为默认它们都是用Object对象来实现比较的,所以它们的hashCode当然是不一样的 我们可以加以下代码检查是否是这样 @Override public int hashCode() { System.out.println(super.hashCode()); return super.hashCode(); } 那么,如何才能去掉重复的对象的 这里我们必须重写hashCode,如下,我们可以把size相同的对象放入同一个桶里,再比较他们的name 把hashCode方法改为 @Override public int hashCode() { System.out.println(size); return size; } 再重写equals(); @Override public boolean equals(Object obj) { if (obj instanceof Ball) { Ball ball = (Ball) obj; return name.equals(ball.getName()); } return false; } 再试试,结果就是为2. hashtable再每添加一个对象的都会先判断他们的hashCode是否一样,如果一样再判断他们是否equals(),如果返回为true的话,那么这个对象将不添加 我们也可以看一下源代码实现
/** * Maps the specified <code>key</code> to the specified * <code>value</code> in this hashtable. Neither the key nor the * value can be <code>null</code>. <p> * * The value can be retrieved by calling the <code>get</code> method * with a key that is equal to the original key. * * @param key the hashtable key * @param value the value * @return the previous value of the specified key in this hashtable, * or <code>null</code> if it did not have one * @exception NullPointerException if the key or value is * <code>null</code> * @see Object#equals(Object) * @see #get(Object) */ public synchronized V put(K key, V value) { // Make sure the value is not null if (value == null) { throw new NullPointerException(); } // Makes sure the key is not already in the hashtable. Entry tab[] = table; int hash = key.hashCode(); int index = (hash & 0x7FFFFFFF) % tab.length; for (Entry<K,V> e = tab[index] ; e != null ; e = e.next) { if ((e.hash == hash) && e.key.equals(key)) { V old = e.value; e.value = value; return old;//这里如果比较结果相同时就返回原来的值 } } modCount++; if (count >= threshold) { // Rehash the table if the threshold is exceeded rehash(); tab = table; index = (hash & 0x7FFFFFFF) % tab.length; } // Creates the new entry. Entry<K,V> e = tab[index]; tab[index] = new Entry<K,V>(hash, key, value, e); count++; return null; }
hashMap允许键与值为空.其他的和hashtable是一样的. 具体可再参考API... 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2009-02-26
最后修改:2009-02-26
要是能加上concurrent一起讨论就好了。。
http://www.iteye.com/topic/164644 |
|
返回顶楼 | |
发表时间:2009-03-05
精彩 到位 3Q
|
|
返回顶楼 | |