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 比较两个Entry的 Key;
if(true){新 value将覆盖Entry 原 value,key不变}
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;
}
4.TreeMap:
基于红黑树(Red-Blacktree)的NavigableMap实现。该映射根据其键的自然顺序进行排序,
或者根据创建映射时提供的Comparator进行排序,具体取决于使用的构造方法
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值可重复
int hash = key.hashCode();
int index = (hash & 0x7FFFFFFF) % tab.length;
7.TreeMap可以对数据进行排序有两种方法,一是实现Comparable接口,二是重写new Comparator()中的方法。其他的数据排序是无序的。