java集合
java中常见的集合都是实现的Collection接口和Map接口
Collection集合(图示只表示了接口的实现和继承,没有表示父类)
![](https://img.haomeiwen.com/i15037928/2032412655db6d6e.png)
初始容量和加载因子
ArrayList的初始容量是10;加载因子为0.5; 扩容增量:原容量的 0.5倍+1;一次扩容后长度为15。
Vector初始容量为10,加载因子是1。扩容增量:原容量的 1倍,如 Vector的容量为10,一次扩容后是容量为20。
HashSet,初始容量为16,加载因子为0.75; 扩容增量:原容量的 1 倍; 如 HashSet的容量为16,一次扩容后容量为32
HashMap,初始容量16,加载因子为0.75; 扩容增量:原容量的 1 倍; 如 HashMap的容量为16,一次扩容后容量为32(HashSet就是基于HashMap实现的)
Map集合(图示只表示了接口的实现和继承,没有表示父类)
![](https://img.haomeiwen.com/i15037928/c0efe9aa0c9ce213.png)
HashMap
HashMap是基于哈希表实现的,每一个元素是一个key-value对,其内部通过单链表解决冲突问题,容量不足(超过了阀值)时,同样会自动增长。
HashMap是非线程安全的,只是用于单线程环境下,多线程环境下可以采用concurrent并发包下的concurrentHashMap。
HashMap中key和value都允许为null。key为null的键值对永远都放在以table[0]为头结点的链表中。
HashMap 实现了Serializable接口,因此它支持序列化,实现了Cloneable接口,能被克隆。
HashMap存数据的过程是:
HashMap内部维护了一个存储数据的Entry数组,HashMap采用链表解决冲突,每一个Entry本质上是一个单向链表。当准备添加一个key-value对时,首先通过hash(key)方法计算hash值,然后通过indexFor(hash,length)求该key-value对的存储位置,计算方法是先用hash&0x7FFFFFFF后,再对length取模,这就保证每一个key-value对都能存入HashMap中,当计算出的位置相同时,由于存入位置是一个链表,则把这个key-value对插入链表头。
indexFor(hash,length)源码中并不是直接对length取余,而是进行h & (length-1)。这也是为什么hashMap的长度只能是2的次方。首先,只有length是2的次方时,h & (length-1)才相当于取余操作。其次,2^n - 1,结果为111...111全1,与操作后不会某位衡为0。比如 length 为 15,则 length - 1 为 14,对应的二进制为 1110,在于 h 与操作,最后一位都为 0 ,而 0001,0011,0101,1001,1011,0111,1101 这几个位置永远都不能存放元素了.
HashMap的两种遍历方式
1.
![](https://img.haomeiwen.com/i15037928/f70bd88371ad9369.png)
将Map集合中的映射关系存入到了Set集合中,而这个映射关系的数据类型是Map.Entry,在通过迭代器将映射关系存入到Map.Entry集合中,并通过其中的getKey()和getValue()放取出键值。
2.
![](https://img.haomeiwen.com/i15037928/044bcc22c4ee041b.png)
将Map集合中的所有键存入到Set集合中,因为Set集合具备迭代器,所以可以用迭代方式取出所有的键,再根据get方法获取每一个键对应的值。简单说就是:Map集合---->Set集合 ---->迭代器取出
HashTable
Hashtable同样是基于哈希表实现的,同样每个元素是一个key-value对,其内部也是通过单链表解决冲突问题,容量不足(超过了阀值)时,同样会自动增长。
Hashtable也是JDK1.0引入的类,是线程安全的,能用于多线程环境中。
Hashtable同样实现了Serializable接口,它支持序列化,实现了Cloneable接口,能被克隆.
Hashtable不允许null作为Key
HashMap和HashTable的区别
(1)HashMap非线程安全,Hashtable线程安全(每个方法中都加入了Synchronize)
(2)前者允许null作为Key(key为null的置于table[0]的链表);后者不允许null作为Key
(3)HashTable直接使用对象的hashCode。而HashMap重新计算hash值(具体方式见上方介绍)
(4)HashTable在不指定容量的情况下的默认容量为11,而HashMap为16,Hashtable不要求底层数组的容量一定要为2的整数次幂,而HashMap则要求一定为2的整数次幂。
(5)Hashtable扩容时,将容量变为原来的2倍加1,而HashMap扩容时,将容量变为原来的2倍。
ConcurrentHashMap和Hashtable的区别
HashTable 使用Synchronize关键字,在每次同步执行时都要锁住整个结构。
ConcurrentHashMap 将 hash 表分为 16 个桶(默认值),诸如get,put,remove 等常用操作只锁当前需要用到的桶。
ConcurrentHashMap具体实现?????
Comparable接口和Comparator接口区别(补充三颗心脏的回答)
(1)实现Compareable接口的对象具有可比性,要实现compareTo(Object obj)方法。向集合里添加时,是调用集合元素的比较方法
(2)实现Comparator接口的集合具有可比性,要实现compare(Object obj,Object obj)方法。向集合添加元素时,调用的是集合的比较方法。
(3)实现Comparable接口要修改元素对象的代码,破坏封装;实现Comparator接口只需要实现比较器。
注:compare(Object,Object)方法保持这个顺序就返回-1,交换顺序就返回1,什么都不做就返回0;
参考 https://blog.csdn.net/qq_25827845/article/details/51287142