集合框架体系
Java 的集合类很多,主要分为两大类,如图 :
- 集合主要是两组(单列集合 , 双列集合)
- Collection 接口有两个重要的子接口 List 、Set , 他们的实现子类都是单列集合
- Map 接口的实现子类是双列集合,存放的 K-V
List接口
基本介绍
1.List的集合类中的元素是有序的,添加和取出顺序是一致的,并且元素可以重复。
2.List的集合类中的每个元素都有对应的顺序索引,即支持索引获取元素,类似数组。
ArrayList集合
- ArrayList可以加入null,并且多个
- ArrayList是由数组来实现数据存储的。底层维护了一个Object类型的数组elementData。
transient Object[] elementData;
transient表示瞬间,短暂的,表示该属性不会被序列号
- 当创建ArrayList对象时,如果使用的是无参构造器,则初始elementData容量为0,第1次添加,则扩容elementData为10,如需要再次扩容,则扩容elementData为1.5倍。如果使用的是指定大小的构造器,则初始elementData容量为指定大小,如果需要扩容,则直接扩容elementData为1.5倍。
- 扩容⽅式是利⽤数组的复制,因此有⼀定的开销。由于数组长度固定,扩容需要创建新的数组拷贝,按1.5倍长度扩容,效率较低。如果插入的数据不是在尾部还要移动数据。
Vector集合
- Vector基本等同于ArrayList,除了ArrayList是线程不安全(执行效率高).在多线程情况下,不建议使用ArrayList
- Vector底层也是一个对象数组,protected Object[] element Date;
- Vector是线程安全的,即线程同步。Vector的操作方法都有synchronized修饰。
- 当创建Vector对象时,如果使用无参构造器,则数组初始化容量是10,如果指定大小,则初始值为指定大小,满后按2倍扩容。
LinkedList集合
- LinkedList底层维护了一个双向链表,维护了两个属性first和last分别指向首节点和尾节点,实现了双向链表和双端队列特点,可以添加任意元素(元素可以重复),包括null。
- 由于底层是双向链表,所以LinkedList的元素的添加和删除,相对数组来说效率较高。
- LinkedList没有实现同步,是线程不安全的
Set接口
基本介绍
- Set接口集合类是无序的,添加和取出元素顺序不一致,并且没有索引。
- 不允许添加重复的元素,最多只能有一个null。
HashSet集合
注
:可以先了解HashMap集合。
- hashSet的本质就是HashMap ,维护了一个数组+链表+红黑树
底层机制
- 存储元素时先通过hashCode方法获取到元素的哈希值。
- 对哈希值进行计算,得到一个索引值,确定在数组中的位置。
- 如果该位置上没有元素,直接放到该位置上。如果该位置上有元素,则需要通过equals方法进行判断,如果相等,则不添加。如果不相等,则以链表的方式添加。
- 在java8中,如果一条链表元素个数达到8,并且数组容量达到64(默认,可以修改),就会进化成红黑树结构。
- 第一次添加元素时,table数组扩容到16,并且有一个临界值=当前容量*加载因子(默认0.75),所以一开始临界值为12,当数组使用到了12时,就会进行2倍扩容,不需要到16等数组满。
LinkedHashSet集合
- LinkedHashSet是 HashSet的子类,不允许添加重复元素,但是元素是有序的。
- LinkedHashSet底层是一个 LinkedHashMap,底层维护了一个数组+双向链表(有head和tail元素)
- LinkedHashSet根据元素的hashCode值来决定元素的存储位置,每个节点上有before和after元素,使用链表维护元素的次序,这使得元素看起来是以插入顺序保存的。
底层机制
- 如图,LinkedHashSet底层维护了一个数组+双向链表,在添加元素时,先求hash值,然后求索引,确定元素在数组中的位置。
- 如果该位置上没有元素,直接放到该位置上。如果该位置上有元素,则需要通过equals方法进行判断,如果相等,则不添加。如果不相等,则添加到双向链表中。
- 这样我们在遍历LinkedHashSet时,可以确保插入顺序和取出顺序是一致的。
Map接口
注
:这里讲的是JDK8的Map接口特点
- Map与Collection并列存在。用于保存具有映射关系的数据:Key-Value。
- Map 中的key和 value可以是任何引用类型的数据,会封装到HashMap$Node对象中。
- Map中的key不允许重复,原因和HashSet一样,Map中的value可以重复。
- Map的key可以为null, value也可以为null,注意key为null, 只能有一个,value为null ,可以多个。
- key和 value之间存在单向一对一关系,即通过指定的key 总能找到对应的value。
HashMap集合
- Map存放数据的key-value示意图,一对k-v是放在一个HashMap$Node中的。
- HashMap没有实现同步,因此是线程不安全的,方法没有做同步互斥的操作,没有synchronized
底层机制
- 存储元素时先通过hashCode方法获取到元素的哈希值。
- 对哈希值进行计算,得到一个索引值,确定在数组中的位置。
- 如果该位置上没有元素,直接放到该位置上。如果该位置上有元素,则需要通过equals方法进行判断,如果相等,则不添加。如果不相等,则以链表的方式添加。
- 在java8中,如果一条链表元素个数达到8,并且数组容量达到64(默认,可以修改),就会进化成红黑树结构。
- 第一次添加元素时,table数组扩容到16,并且有一个临界值=当前容量*加载因子(默认0.75),所以一开始临界值为12,当数组使用到了12时,就会进行2倍扩容,不需要到16等数组满。
注
:可以配合HashSet中的图进行理解。
Hashtable
- 存放的元素是键值对:即K-V
- hashtable的键和值都不能为null,否则会抛出NullPointerException
- hashTable使用方法基本上和HashMap一样
- hashTable是线程安全的(synchronized),所以效率较低
Collections 工具类
Collections 工具类介绍
- Collections是一个操作 Set、List和Map等集合的工具类
- Collections中提供了一系列静态的方法对集合元素进行排序、查询和修改等操作
排序操作
均为 static 方法
-
reverse(List)
: 反转 List中元素的顺序 -
shuffle(List)
: 对List集合元素进行随机排序 -
sort(List)
: 根据元素的自然顺序对指定List集合元素按升序排序 -
sort(List, Comparator)
: 根据指定的Comparator产生的顺序对 List集合元素进行排序 -
swap(List,int,int)
: 将指定list集合中的i处元素和j处元素进行交换
查找、替换
-
Object max(Collection)
:根据元素的自然顺序,返回给定集合中的最大元素 -
Object max(Collection, Comparator)
:根据Comparator指定的顺序,返回给定集合中的最大元素 -
Object min(Collection)
;根据元素的自然顺序,返回给定集合中的最小元素 -
Object min(Collection,Comparator)
;根据Comparator指定的顺序,返回给定集合中的最小元素 -
int frequency(Collection,object)
:返回指定集合中指定元素的出现次数 -
void copy(List dest,List src)
:将src中的内容复制到dest中 -
boolean replaceAll(List list,Object oldVal, Object newVal)
:使用新值替换List 对象的所有旧值