HashMap,HashSet,Hashtable以及TreeMap的原理和区别

1.HashMap:HashMap是一个数组和链表的结合体(在数据结构称“链表散列“),当我们往hashMap中put元素的时候,先根据key的hash值得到这个元素在数组中的位置(即下标),然后就可以把这个元素放到对应的位置中了。如果这个元素所在的位子上已经存放有其他元素了,那么在同一个位子上的元素将以链表的形式存放,新加入的放在链头,最先加入的放在链尾。HashMap实现了Map接口,继承AbstractMap它是基于哈希表的Map接口的实现(保证键的唯一性),以key-value的形式存在。

构造方法cv

描述

HashMap()

构造一个具有默认初始容量 (16) 和默认加载因子 (0.75) 的空 HashMap

HashMap(intinitialCapacity)

构造一个带指定初始容量和默认加载因子 (0.75)的空 HashMap

HashMap(intinitialCapacity, floatloadFactor)

构造一个带指定初始容量和加载因子的空 HashMap


  初始容量:表示哈希表中桶的数量,初始容量是创建哈希表时的容量,就是集合的容量

  加载因子:哈希表在其容量自动增加之前可以达到多满的一种尺度,它衡量的是一个散列表的空间的使用程度,负载因子越大表示散列表的装填程度越高,反之愈小.

 

HashMap结构:

一开始有少量的 HashBucket,当程序试图将一个key-value(Entry) 放入HashMap中时,程序首先根据该key hashCode()返回值决定该 Entry Bucket位置如果该Bucket为空,直接存放入该Bucket;

如果该Bucket不为空,使用equals 比较两个EntryKey

if(true){value将覆盖Entry valuekey不变}

if(false){Entry将与Bucket中原Entry形成 Entry链,而且新Entry位于 Entry 链的头部}

按照以上规则,不断向HashMap中添加元素,

空间会不会不够用?

一个桶里拜访的东西太多,找起来的性能?

如果已存放的 entry超过 threshold临界值,

   threshold = Bucket数的loadFactor(默认值0.75),

则会动态扩容 Bucket(默认值为2原总数)

并将 Bucket Entry 重新排列 。以此类推

2.HashSet:

每次存储对象的时候, 调用对象的hashCode()方法,计算一个哈希值.

在集合中查找是否包含哈希值相同的元素.
如果没有哈希值相同元素
, 直接存入.
如果有哈希值相同的元素
, 逐个使用equals()方法比较
比较结果全为
false就存入.
如果比较结果有
true则不存.

HashSet内部就是使用Hashmap实现的,和Hashmap不同的是它不需要Key和Value两个值。        

往hashset中插入对象其实只不过是内部做了

            public boolean add(Object o) {

                      return map.put(o, PRESENT)==null;
            }



3.Hashtable:HashTable基于Dictionary,是Map接口的一个实现类,Hashtable和HashMap它们两个内部实现方式的数组的初始大小和扩容的方式。HashTable中hash数组默认大小是11,增加的方式是 old*2+1。HashMap中hash数组的默认大小是16,而且一定是2的指数。


4.TreeMap:

基于红黑树(Red-Blacktree)的NavigableMap实现。该映射根据其键的自然顺序进行排序

或者根据创建映射时提供的Comparator进行排序,具体取决于使用的构造方法

TreeMap   继承于 AbstractMap ,所以它是一个 Map ,即一个 key-value 集合
TreeMap 实现了 Cloneable 接口,意味着它能被 克隆
TreeMap 实现了 Java .io.Serializable 接口,意味着它支持序列化
TreeMap按默认的自然排序的升序进行排序

区别:
1.HashMap,TreeMap,Hashtable都是按照键值对使用put(key,value)方法存储对象的,而HashSet存储的是对象本身,使用add(e)方法添加元素对象的。HashMap的key和Value可以为空,HashTable的key和Value都不允许为空,TreeMap的key和Value都可以为空,但是key不可以是null,value值可以是null。
2.继承方式不同,HashMap继承的是AbstractMap
,HashTable继承的是Dictionary,HashSet继承的是AbstractSet,TreeMap继承的是AbstractMap
3.HashTable是线程同步的,其他均是非线程同步的

4.遍历的方式不同,Hashtable、HashMap都使用了 Iterator,但是HashSet还实现了Enumeration的方式。
5.hashSet不允许存储重复的值,其他map型存储元素时,key值必须唯一,value值可重复
6.哈希值的使用不同,HashTable直接使用对象的hashCode,如下:

   int hash = key.hashCode();
      int index = (hash & 0x7FFFFFFF) % tab.length;

   而HashMap使用键对象重新计算hash值,而且用 与代替求模。HashSet使用成员对象来计算hashcode值,对于两个对象来说hashcode可能相同,所以equals()方法用来判断对象的相等性,如果两个对象不同的话,那么返回false。

7.TreeMap可以对数据进行排序有两种方法,一是实现Comparable接口,二是重写new Comparator()中的方法。其他的数据排序是无序的。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值