• HashMap和Hashtable的区别


    0.出现时间?

      HashMap是jdk1.2

      Hashtable是jdk1.1

      HashMap出现得晚

    1.线程安全?

    HashMap线程不安全  Collections.synchronizedMap(map);

    Hashtable线程安全  synchronized

    2.null key?

      HashMap允许 null key。但是,null key只能有一个,null value可以有多个

      Hashtable不允许null key 和 null value,空指针异常

      由于HashMap允许null值,因此,当get(key)返回null时,两种情况:

        该key对应的value为null

        map中不存在该key

      因此,判断一个map中是否含有key时,应使用containsKey(key)

    3.父类

    public class HashMap<K,V> extends AbstractMap<K,V> implements Map<K,V>, Cloneable, Serializable

    public class Hashtable<K,V> extends Dictionary<K,V> implements Map<K,V>, Cloneable, java.io.Serializable

    继承的父类不同,实现的接口相同

    Dictionary是一个已经废弃的类

    4.初始容量、加载因子

      HashMap:

        static final int DEFAULT_INITIAL_CAPACITY = 1 << 4;

        static final int MAXIMUM_CAPACITY = 1 << 30;

        static final float DEFAULT_LOAD_FACTOR = 0.75f;

        扩容:resize(2 * table.length);

        HashMap的长度总是2的n次方。

        如果在创建HashMap对象时,指定了初始大小,并且该大小不是2的n次方时,会自动调整为比指定值大的最接近的2的n次方;如果指定的初始大小大于MAXIMUM_CAPACITY ,则初始为MAXIMUM_CAPACITY 

    public HashMap() {
      this(DEFAULT_INITIAL_CAPACITY, DEFAULT_LOAD_FACTOR);
    }

      Hashtable:

        初始:11

        加载因子:0.75F

        int newCapacity = (oldCapacity << 1) + 1;

        HashTable的总长度会尽量使用素数、奇数。

        如果在创建Hashtable对象时,手动指定了初始化大小,就直接使用给定的值

    public Hashtable() {
      this(11, 0.75f);
    }

     

    5.hashCode计算

      当哈希表的长度为素数(Hashtable)时,取模的结果更均匀,冲突少

      当哈希表的长度为2的幂可以使用位运算得到结果,位运算效率高,由于使用2的幂长度的哈希表,冲突增加,所以,HashMap在得到key的hashcode之后,有做了一些处理,使冲突减少

      HashMap

    int hash = hash(key);// 在得到对象的hash值之后,通过一系列的位运算打散数据,减少hash冲突
    int i = indexFor(hash, table.length);  return h & (length-1);// 使用位运算得到键值对存储的位置

      Hashtable

    int hash = hash(key);// 计算key的哈希值,就是对象的hash值
    int index = (hash & 0x7FFFFFFF) % tab.length;// 哈希表的长度是素数或者奇数,直接取余就是该键值对在哈希表中存储的位置

    6.底层实现

    1.7都是数组+链表

    private transient Entry<K,V>[] table;

    HashMap 和 Hashtable 底层都是Entry<K,V>(内部类)

    HashMap:static class Entry<K,V> implements Map.Entry<K,V>

    Hashtable:private static class Entry<K,V> implements Map.Entry<K,V>

     

    7.遍历方式

    Iterator

    Hashtable还使用了Enumeration

    HashMap的Iterator是fail-fast迭代器

    JDK8之前,Hashtable是没有fast-fail机制的。JDK8 ,HashTable也是使用fast-fail的

    当有其它线程改变了HashMap的结构(增加,删除,修改元素),将会抛出ConcurrentModificationException。不过,通过Iterator的remove()方法移除元素则不会抛出ConcurrentModificationException异常。

    8.API

      Hashtable比HashMap多两个public 方法

      elements()这个方法来自于抽象类Dictionary,该类已经废弃。

      contains()  containsValue()方法内部调用了该方法,实现的是同样的功能  

    public boolean containsValue(Object value) {
      return contains(value);
    }

      

  • 相关阅读:
    20199118 2019-2020-2《网络攻防实践》第七周作业
    20199118 2019-2020-2 《网络攻防实践》第六周作业
    20199118 2019-2020-2 《网络攻防实践》第五周作业
    20199118《网络攻防实践》第四周作业
    C#调用webservice 不用默认配置文件 直接在构造函数配置地址
    SQL 字符串分隔函数
    查询Sqlserver数据库死锁的一个存储过程
    C# 守护进程 Windows服务 启动 exe
    SQLSERVER 存储过程中的事务
    EFCore连接Mysql DBFirst模式生成model
  • 原文地址:https://www.cnblogs.com/duanjiapingjy/p/9536521.html
Copyright © 2020-2023  润新知