集合主要分为两大系列Collection接口和Map接口,Collection 表示一组对象,Map表示一组映射关系或键值对。
Colletion的子接口有List、Set和Queue,List的实现类有ArrayList、LinkedList、Vector,
Set的实现类有HashSet和TreeSet,Map的实现类有HashMap、Hashtable和TreeMap,
LinkedHashMap是HashMap的子类,Properties是HashTable的子类。
Vector、HashTable、Properties是线程安全的;
ArrayList、LinkedList、HashSet、TreeSet、HashMap、TreeMap等都是线程不安全的。
List接口特点:
- List集合所有的元素是以一种线性方式进行存储的,例如,存元素的顺序是11、22、33。那么集
合中,元素的存储就是按照11、22、33的顺序完成的) - 它是一个元素存取有序的集合。即元素的存入顺序和取出顺序有保证。
- 它是一个带有索引的集合,通过索引就可以精确的操作集合中的元素(与数组的索引是一个道
理)。 - 集合中可以有重复的元素,通过元素的equals方法,来比较是否为重复的元素。
List集合类中元素有序、且可重复。这就像银行门口客服,给每一个来办理业务的客户分配序号:第一
个来的是“张三”,客服给他分配的是0;第二个来的是“李四”,客服给他分配的1;以此类推,最后一个
序号应该是“总人数-1”。
注意:
List集合关心元素是否有序,而不关心是否重复,请大家记住这个原则。例如“张三”可以领取两个号。
Set接口是Collection的子接口,set接口没有提供额外的方法。但是比 Collection 接口更加严格了。
Set 集合不允许包含相同的元素,如果试把两个相同的元素加入同一个 Set 集合中,则添加操作失败。
Set集合支持的遍历方式和Collection集合一样:foreach和Iterator。
Set的常用实现类有:HashSet、TreeSet、LinkedHashSet。
Set集合类无序不可重复。
1、谈谈HashMap
HashMap基于哈希表的Map接口实现,是以key-value存储形式存在,即主要用来存放键值对。
HashMap 的实现不是同步的,它不是线程安全的。HashMap存取是无序的,键位置是唯一的,键和值
位置都可以是null,但是键位置只能是一个null。它是按照两倍的扩容的。
JDK1.8 之前 HashMap 由 数组+链表 组成的,数组是 HashMap 的主体,链表则是主要为了解决哈
希冲突(两个对象调用的hashCode方法计算的哈希码值一致导致计算的数组索引值相同)而存在的(“拉
链法”解决冲突).JDK1.8 以后在解决哈希冲突时有了较大的变化,当链表长度大于阈值(或者红黑树的
边界值,默认为 8)并且当前数组的长度大于64时,此时此索引位置上的所有数据改为使用红黑树存
储。
2、HashMap的几个重要参数静态常量
初始化容量16
默认的负载因子,默认值是0.75
static final float DEFAULT_LOAD_FACTOR = 0.75f;
集合最大容量:2的30次幂
//集合最大容量的上限是:2的30次幂
static final int MAXIMUM_CAPACITY = 1 << 30;
阈值:8,当链表的值超过8则会转红黑树(1.8新增)
//当桶(bucket)上的结点数大于这个值时会转成红黑树
static final int TREEIFY_THRESHOLD = 8;
当链表的值小于6则会从红黑树转回链表
//当桶(bucket)上的结点数小于这个值时树转链表
static final int UNTREEIFY_THRESHOLD = 6;
3、HashMap什么时候进行扩容呢?
当hashmap中元素个数超过16x0.75=12的时候会进行扩容。在不断的添加数据的过程中,会涉及到扩容问题,当超出临界值(且要存放的位置非空)时,扩容。默认的扩容方式:扩容为原来容量的2倍,并将原有的数据复制过来。
当hashmap中的元素个数超过数组大小loadFactor时,就会进行数组扩容,loadFactor的默认值为0.75,也就是说,默认情况下,数组大小为16,那么当hashmap中元素