`
行者买刀
  • 浏览: 192080 次
  • 性别: Icon_minigender_1
  • 来自: 厦门
社区版块
存档分类
最新评论

浅谈Hashtable与HashMap

 
阅读更多

超级本本降价风暴

  

     提到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...

分享到:
评论
2 楼 joney.xia 2009-03-05  
精彩 到位 3Q
1 楼 jiyanliang 2009-02-26  
要是能加上concurrent一起讨论就好了。。
http://www.iteye.com/topic/164644

相关推荐

Global site tag (gtag.js) - Google Analytics