Java中HashMap和Hashtable之间的区别是什么?

对于非线程应用程序,哪个更有效?


当前回答

哈希表:

Hashtable是一种保留键值对值的数据结构。它不允许键和值都为null。如果添加null值,将获得NullPointerException。它是同步的。因此,它有其成本。在特定时间,只有一个线程可以访问HashTable。

例子:

import java.util.Map;
import java.util.Hashtable;

public class TestClass {

    public static void main(String args[ ]) {
    Map<Integer,String> states= new Hashtable<Integer,String>();
    states.put(1, "INDIA");
    states.put(2, "USA");

    states.put(3, null);    //will throw NullPointerEcxeption at runtime

    System.out.println(states.get(1));
    System.out.println(states.get(2));
//  System.out.println(states.get(3));

    }
}

哈希映射:

HashMap类似于Hashtable,但它也接受键值对。它允许键和值都为空。它的性能优于HashTable,因为它是非同步的。

例子:

import java.util.HashMap;
import java.util.Map;

public class TestClass {

    public static void main(String args[ ]) {
    Map<Integer,String> states = new HashMap<Integer,String>();
    states.put(1, "INDIA");
    states.put(2, "USA");

    states.put(3, null);    // Okay
    states.put(null,"UK");

    System.out.println(states.get(1));
    System.out.println(states.get(2));
    System.out.println(states.get(3));

    }
}

其他回答

除了izb所说的,HashMap允许空值,而Hashtable不允许。

还要注意,Hashtable扩展了Dictionary类,作为Javadocs状态,该类已过时,已被Map接口取代。

HashTable是同步的,如果您在单个线程中使用它,则可以使用HashMap,这是一个未同步的版本。未同步的对象通常性能更高。顺便说一句,如果多个线程同时访问HashMap,并且至少有一个线程在结构上修改了该映射,那么它必须在外部同步。您可以使用以下方法将未同步的映射打包到已同步的映射中:Map m=Collections.synchronizedMap(新HashMap(…));HashTable只能包含非空对象作为键或值。HashMap可以包含一个空键和空值。Map返回的迭代器是快速失败的,如果在创建迭代器之后的任何时候对映射进行了结构修改,则除了通过迭代器自己的remove方法之外,迭代器将抛出ConcurrentModificationException。因此,在并发修改的情况下,迭代器会快速而干净地失败,而不是在未来某个不确定的时间冒着任意、非确定性行为的风险。而Hashtable的键和元素方法返回的枚举不会快速失败。HashTable和HashMap是Java集合框架的成员(自从Java 2平台v1.2以来,HashTable被改进以实现Map接口)。HashTable被认为是遗留代码,如果需要线程安全的高度并发实现,文档建议使用ConcurrentHashMap代替HashTable。HashMap不保证返回元素的顺序。对于HashTable,我想它是相同的,但我不完全确定,我找不到明确说明这一点的ressource。

已经发布了许多好答案。我补充了一些新的观点并总结了一下。

HashMap和Hashtable都用于以键和值的形式存储数据。它们都使用哈希技术来存储唯一的键。但是HashMap和Hashtable类之间有很多不同,如下所示。

哈希图

HashMap未同步。它不是线程安全的,如果没有适当的同步代码,就无法在多个线程之间共享。HashMap允许一个空键和多个空值。HashMap是JDK1.2中引入的一个新类。HashMap速度很快。我们可以通过调用以下代码使HashMap同步Map m=Collections.synchronizedMap(HashMap);Iterator遍历HashMap。HashMap中的迭代器快速失败。HashMap继承AbstractMap类。

哈希表

哈希表已同步。它是线程安全的,可以与多个线程共享。哈希表不允许空键或值。Hashtable是一个遗留类。哈希表很慢。哈希表是内部同步的,不能不同步。枚举器和迭代器遍历哈希表。Hashtable中的枚举器不会快速失败。Hashtable继承Dictionary类。

进一步阅读Java中HashMap和Hashtable之间的区别是什么?

哈希表:

Hashtable是一种保留键值对值的数据结构。它不允许键和值都为null。如果添加null值,将获得NullPointerException。它是同步的。因此,它有其成本。在特定时间,只有一个线程可以访问HashTable。

例子:

import java.util.Map;
import java.util.Hashtable;

public class TestClass {

    public static void main(String args[ ]) {
    Map<Integer,String> states= new Hashtable<Integer,String>();
    states.put(1, "INDIA");
    states.put(2, "USA");

    states.put(3, null);    //will throw NullPointerEcxeption at runtime

    System.out.println(states.get(1));
    System.out.println(states.get(2));
//  System.out.println(states.get(3));

    }
}

哈希映射:

HashMap类似于Hashtable,但它也接受键值对。它允许键和值都为空。它的性能优于HashTable,因为它是非同步的。

例子:

import java.util.HashMap;
import java.util.Map;

public class TestClass {

    public static void main(String args[ ]) {
    Map<Integer,String> states = new HashMap<Integer,String>();
    states.put(1, "INDIA");
    states.put(2, "USA");

    states.put(3, null);    // Okay
    states.put(null,"UK");

    System.out.println(states.get(1));
    System.out.println(states.get(2));
    System.out.println(states.get(3));

    }
}

请记住,HashTable是在引入Java集合框架(JCF)之前的遗留类,后来经过了修改以实现Map接口。Vector和Stack也是如此。

因此,在新代码中始终远离它们,因为正如其他人所指出的,JCF中总是有更好的替代方案。

这是Java集合备忘单,您会发现它很有用。请注意,灰色块包含旧类HashTable、Vector和Stack。