java:hashmap和hashtable的区别

文章目录

    • 1.继承不同
    • 2.线程安全不一样
    • 3.允不允许null值
    • 4.遍历方式的内部实现上不同
    • 5.哈希值的使用不同
    • 6.内部实现方式的数组的初始大小和扩容的方式不一样

1.继承不同

第一个不同主要是历史原因。Hashtable是基于陈旧的Dictionary类的,HashMap是Java 1.2引进的Map接口的一个实现。

public class HashMap extends AbstractMap implements Cloneable, Serializable {...}
public class Hashtable extends Dictionary implements Map, Cloneable, Serializable {...}

而HashMap继承的抽象类AbstractMap实现了Map接口:

public abstract class AbstractMap implements Map {...}

2.线程安全不一样

Hashtable 中的方法是同步的,而HashMap中的方法在默认情况下是非同步的。在多线程并发的环境下,可以直接使用Hashtable,但是要使用HashMap的话就要自己增加同步处理了。

这是Hashtable的put()方法:

/*
     * Associate the specified value with the specified key in this
     * {@code Hashtable}. If the key already exists, the old value is replaced.
     * The key and value cannot be null.
     *
     * @param key
     *            the key to add.
     * @param value
     *            the value to add.
     * @return the old value associated with the specified key, or {@code null}
     *         if the key did not exist.
     * @see #elements
     * @see #get
     * @see #keys
     * @see java.lang.Object#equals
 */
    public synchronized V put(K key, V value) {
        if (key == null) {
            throw new NullPointerException("key == null");
        } else if (value == null) {
            throw new NullPointerException("value == null");
        }
        int hash = Collections.secondaryHash(key);
        HashtableEntry[] tab = table;
        int index = hash & (tab.length - 1);
        HashtableEntry first = tab[index];
        for (HashtableEntry e = first; e != null; e = e.next) {
            if (e.hash == hash && key.equals(e.key)) {
                V oldValue = e.value;
                e.value = value;
                return oldValue;
            }
        }

Hashmap的put方法

//这是HashMap的put()方法:
/**
     * Maps the specified key to the specified value.
     *
     * @param key
     *            the key.
     * @param value
     *            the value.
     * @return the value of any previous mapping with the specified key or
     *         {@code null} if there was no such mapping.
     */
    @Override public V put(K key, V value) {
        if (key == null) {
            return putValueForNullKey(value);
        }

        int hash = Collections.secondaryHash(key);
        HashMapEntry[] tab = table;
        int index = hash & (tab.length - 1);
        for (HashMapEntry e = tab[index]; e != null; e = e.next) {
            if (e.hash == hash && key.equals(e.key)) {
                preModify(e);
                V oldValue = e.value;
                e.value = value;
                return oldValue;
            }
        }

从上面的源代码可以看到Hashtable的put()方法是synchronized的,而HashMap的put()方法却不是。

3.允不允许null值

从上面的put()方法源码可以看到,Hashtable中,key和value都不允许出现null值,否则会抛出NullPointerException异常。
而在HashMap中,null可以作为键,这样的键只有一个;可以有一个或多个键所对应的值为null。当get()方法返回null值时,即可以表示 HashMap中没有该键,也可以表示该键所对应的值为null。因此,在HashMap中不能由get()方法来判断HashMap中是否存在某个键, 而应该用containsKey()方法来判断。

4.遍历方式的内部实现上不同

Hashtable、HashMap都使用了 Iterator。而由于历史原因,Hashtable还使用了Enumeration的方式 。

5.哈希值的使用不同

HashTable直接使用对象的hashCode。而HashMap重新计算hash值。

6.内部实现方式的数组的初始大小和扩容的方式不一样

HashTable中的hash数组初始大小是11,增加的方式是 old*2+1。HashMap中hash数组的默认大小是16,而且一定是2的指数。

数据类型 线程安全 允许空值 效率 contain方法 继承类 时间
HashMap 线程不安全 允许有null的键和值 效率高一点 有containsvalue和containsKey方法 Map interface 的一个实现 HashMap是Hashtable的轻量级实现
Hashtable 线程安全 不允许有null的键和值 效率稍低一点 有contains方法方法 继承于Dictionary 类 Hashtable 比HashMap 要旧

你可能感兴趣的:(后台开发面试题,Java)