Java中的HashMap和Hashtable有什么区别?

Java中的HashMap和Hashtable有什么区别?,java,collections,hashmap,hashtable,Java,Collections,Hashmap,Hashtable,Java中a和a的区别是什么 哪个对非线程应用程序更有效?根据这些信息,我建议使用HashMap。我认为最大的优点是Java将阻止您在迭代时修改它,除非您通过迭代器进行修改。哈希表是同步的,而哈希映射不是。这使得Hashtable比Hashmap慢 对于单线程应用程序,请使用HashMap,因为它们在功能上是相同的。Hashtable类似于HashMap,并且具有类似的接口。建议您使用HashMap,除非您需要对传统应用程序的支持或需要同步,因为Hashtables方法是同步的。因此,在您不是多

Java中a和a的区别是什么


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

根据这些信息,我建议使用HashMap。我认为最大的优点是Java将阻止您在迭代时修改它,除非您通过迭代器进行修改。

哈希表
是同步的,而
哈希映射
不是。这使得
Hashtable
Hashmap


对于单线程应用程序,请使用
HashMap
,因为它们在功能上是相同的。

Hashtable
类似于
HashMap
,并且具有类似的接口。建议您使用
HashMap
,除非您需要对传统应用程序的支持或需要同步,因为
Hashtables
方法是同步的。因此,在您不是多线程的情况下,
HashMap
是您最好的选择。

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


还请注意,
哈希表
扩展了
字典
类,该类作为状态已过时,并已被
映射
接口所取代。

对于线程应用,您通常可以使用ConcurrentHashMap,这取决于您的性能要求。

Java和之间存在一些差异:

  • Hashtable
    是,而
    HashMap
    不是。这使得非线程应用程序的
    HashMap
    更好,因为非同步对象通常比同步对象的性能更好

  • Hashtable
    不允许
    null
    键或值
    HashMap
    允许一个
    null
    键和任意数量的
    null

  • HashMap的一个子类是,因此在需要可预测的迭代顺序(默认情况下是插入顺序)的情况下,可以轻松地将
    HashMap
    替换为
    LinkedHashMap
    。如果您使用的是
    哈希表
    ,那么这就不那么容易了


  • 由于同步对您来说不是问题,我建议您使用
    HashMap
    。如果出现同步问题,您还可以查看。

    HashMap
    :使用哈希代码索引数组的
    Map
    接口的实现。
    哈希表
    :您好,1998呼叫。他们想要回他们的收藏API


    不过说真的,你最好还是远离哈希表。对于单线程应用程序,您不需要额外的同步开销。对于高度并发的应用程序,偏执的同步可能会导致饥饿、死锁或不必要的垃圾收集暂停。正如Tim Howland指出的,您可以使用
    ConcurrentHashMap

    注意,很多答案都表示哈希表是同步的在实践中,这为您带来的好处很少。同步在访问器/变异器上。方法将停止两个线程同时添加或从映射中删除,但在现实世界中,您通常需要额外的同步

    一个非常常见的习惯用法是“先检查后放置”——即在
    映射中查找条目,如果该条目不存在,则添加该条目。无论您使用的是
    Hashtable
    还是
    HashMap
    ,这都不是原子操作

    可通过以下方式获得等效同步的
    HashMap

    Collections.synchronizedMap(myMap);
    
    但要正确执行此逻辑,您需要对表单进行额外的同步:

    synchronized(myMap) {
        if (!myMap.containsKey("tomato"))
            myMap.put("tomato", "red");
    }
    
    即使迭代
    哈希表
    的条目(或
    集合获得的
    哈希映射
    。synchronizedMap
    )也不是线程安全的,除非您还保护
    映射
    ,防止通过其他同步进行修改

    接口的实现(例如)通过包括线程安全检查,然后执行语义来解决一些问题,例如:

    ConcurrentMap.putIfAbsent(key, value);
    

    哈希表
    被视为遗留代码。使用
    HashMap
    HashMap
    的派生,没有任何关于
    Hashtable
    的事情不能完成,因此对于新代码,我看不出有任何理由返回到
    Hashtable

    Hashtable和hashmap之间的另一个关键区别是hashmap中的迭代器故障快,而Hashtable的枚举器故障快,如果任何其他线程通过添加或删除任何元素,但迭代器自己的remove()方法除外。但这并不是一个有保证的行为,JVM将尽最大努力完成。”


    我的资料来源:

    面试中经常会问这个问题,以检查应聘者是否理解集合类的正确用法,是否知道可用的替代解决方案

  • HashMap
    类大致相当于
    Hashtable
    ,除了它是非同步的并且允许空值之外。(
    HashMap
    允许空值作为键和值,而
    Hashtable
    不允许
    null
    s)
  • HashMap
    不能保证映射顺序随时间保持不变
  • HashMap
    是非同步的,而
    Hashtable
    是同步的
  • HashMap
    中的迭代器是故障安全的,
    Hashtable
    的枚举器不是,如果任何其他线程通过添加或删除除
    Iterator
    自己的
    remove()之外的任何元素来修改映射,则抛出
    ConcurrentModificationException
    方法。但这不是一种保证的行为,JVM将尽最大努力完成
  • 请注意一些重要术语:

  • 同步意味着只有一个线程可以修改
    for (Elem elem : map.keys()) {
      elem.doSth();
    }
    
    for (Enumeration en = htable.keys(); en.hasMoreElements(); ) {
      Elem elem = (Elem) en.nextElement();
      elem.doSth();
    }
    
    Map<String,Integer> map = { "orange" : 12, "apples" : 15 };
    map["apples"];
    
    Map m = Collections.synchronizedMap(new HashMap(...));
    
    Map m = Collections.synchronizedMap(hashMap);
    
    Map hashmap = new HashMap();
    
    Map map = Collections.SyncronizedMap(hashmap);
    
    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));
    
        }
    }
    
    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));
    
        }
    }