1、集合【collection】【单列集合】
集合用来存储不同类型的对象(基本数据类型除外),存储长度可变。
collection框架图:
1.1.1、Collection子类
Collection接口被List接口和Set接口所继承;
List接口有三个实现类:ArrayList,LinkedList,Vector
Set接口被HashSet类实现,被SortedSet接口继承,同时TreeSet类实现SortedSet接口,LinkedHashSet类继承HashSet类;
1.1.2、Collection通用方法
Collection接口是单列集合的最顶层接口
定义了一些通用的方法:
add(E e)添加元素;
clear()清空元素;
remove(E e)移除元素;
size()元素数量;
toArray()集合转数组;
contains(E e)判断元素是否存在;
isEmpty()判断集合是否为空;
Collection集合的方法:
1.2、List
特点:
- 有索引,
- 精准操作元素
- 元素有序,存储及取出时顺序一致
- 元素可重复
List利用索引(index),定义了一些特殊方法:
add(intindex,E e) 将元素添加到指定位置;
remove(int index) 移除指定位置的元素;
set(int index,E e) 用元素替换指定位置的元素;
get(int index,E e) 获取指定位置的元素;
ListIterator listIterator() 列表迭代器
List subList(int fromIndex,int toIndex) 截取集合
1.2.1、ArrayList
数据结构:数组
优点: 查询快,增删慢
缺点: 线程不安全,效率高
底层分析:
1、数组结构是有序的元素序列,需在内存中开辟一段连续的地址空间,用于元素的存放。每个空间都有自己的索引编号,通过索引可以快速找到相应元素,因此查询效率高;
2、数组初始化时长度是固定的,若想增删元素,就必须新创建一个数组,把源数组元素复制给新数组,随后源数组销毁,耗时长,因此增删慢。
默认容量为: 10
扩容:
ArrayList每次扩容大小为原来的1.5倍,
list扩容实质是数组copy,将原数据复制到新数组,指针指向新数组。
1.2.3、LinkedList
数据结构:双向链表
优点: 查询慢,增删快
缺点: 线程不安全,效率高
底层分析:
1、双向链表顾名思义,就是两条链表。一条链表存储数据,另一条连表存储数据存入顺序;因此单向链表结构无序,双向链表结构有序。
2、链表的增删只需在原有的基础上连上链子或切断链子,因此增删快;链表结构没有索引,因此查询慢。
特有方法:
addFirst(E e) 添加元素到开头,头插;
addLast(E e) 添加元素到结尾,尾插;
push(E e) 将元素推入所在堆栈;
pop() 从所在堆栈中获取一个元素
getFirst() 返回开头元素;
getLast() 返回结尾元素;
1.2.3、Vector【JDK1.0就出现了,存在一些缺点,不建议使用。】
数据结构:数组
优点: 查询快,增删慢
缺点: 线程安全,效率低
底层分析:
1、底层由数组实现,因此与arrayList具有相似的特性
2、Vector是线程安全的,效率低,而ArrayList是线程不安全的,但效率高。
1.3、Set【与Collection 接口的方法基本一致】
特点:
元素不可重复
元素无序,存储及取出时顺序不一致
没有索引,不能使用普通For循环遍历
1.3.1、HashSet
数据结构:
JDK1.8之前:哈希表(数组+单向链表)
JDK1.8之后:哈希表(数组+单向链表+红黑树)当链表长度超过阈值[ 8 ]时链表将转换为红黑树。
特点:查询快,元素无序,元素唯一,没有索引
底层分析:
1、JDK1.8之前的哈希表底层用数组+单向链表实现。哈希表用链表处理hash冲突,即同一Hash值的元素存储在一个链表里,但是当一个链表中的元素较多(即Hash值相等的元素较多),通过key值依次查找的效率就会降低。因此JDK1.8之后,哈希表底层采用数组+单向链表+红黑树实现
2、JDK1.8之后,哈希表底层采用数据+单向链表+红黑树实现,当链表长度超过阈值(8)时,链表将转换为红黑树,极大缩短查询时间。
元素的唯一性:
元素的唯一性是靠所存储元素类型是否重写hashCode()和equals()方法来保证的,
如果没有重写这两个方法,则无法保证元素的唯一性
具体实现唯一性的比较过程:
存储元素首先会使用hash()算法函数生成一个int类型hashCode散列值,然后与已存储元素的hashCode值比较, 如果hashCode不相等,则所存储的两个对象一定不相等,此时便直接将存储元素存储在hashCode散列值处
如果hashCode相等,存储元素与已存储元素不一定相等,此时会调用equals()方法判断两个对象的内容是否相等,如果内容相等,那么就是同一个对象,则不进行存储;如果比较的内容不相等,那么就是不同的对象,就需要存储该元素,此时就要采用哈希的地址冲突算法,在当前hashCode值处创建一个新的链表,在同一个hashCode值的后面存储不同的对象,这样就保证了元素的唯一性。
Object类中的hashCode()的方法是所有子类都会继承这个方法,这个方法会用Hash算法算出一个Hash(哈希)码值返回,HashSet会用Hash码值去和数组长度取模, 模(这个模就是对象要存放在数组中的位置)相同时才会判断数组中的元素和要加入的对象的内容是否相同,如果不同才会添加进去。
注意:
哈希值是一个十进制的整数,是对象的地址值,是一个逻辑地址,不是实际存储的物理地址,由系统随机给出。
Object类的int hashCode()方法,可以获取对象的哈希值。
1.3.2、LinkedHashSet
底层数据结构:链表、哈希表
- 链表保证元素有序
- 哈希表保证元素唯一
特点:元素有序、元素不重复,保持唯一性
1.3.3、TreeSet
底层数据结构:红黑树
特点:元素唯一且已经排好序
元素的有序性:由二叉树结构保证。
唯一性同样需要重写 hashCode 和 equals() 方法,
根据构造方法不同,分为自然排序(无参构造)、比较器排序(有参构造),
1、自然排序要求元素必须实现Compareable接口,并重写里面的compareTo()方法,元素通过比较返回的int值来判断排序序列,返回0说明两个对象相同,不需要存储;
2、比较器排需要在TreeSet初始化是时候传入一个实现Comparator接口的比较器对象,或者采用匿名内部类的方式new一个Comparator对象,重写里面的compare()方法;
2、集合【Map】【多列集合】
map框架图:
2.1.1、Map子类
Map接口被hashMap、hashTable所实现,被sortedMap继承
sortedMap接口被treeMap类实现
2.1.2、Map通用方法
特点:元素包含两个值(key,value)即键值对, key不允许重复,value可以重复, key与value是一一对应的且元素无序;
Map接口是双列集合的最顶层接口,定义了一些通用的方法:
put(key , value) 添加元素;
remove(key) 删除key对应元素;
clear() 删除所有元素;
isEmpty() 判断map是否为空
containsKey(key) 判断是否存在key对应元素;
get(key) 获取key对应元素;
KeySet() 获取所有的key,存到Set集合中;
entrySet() 获取所有的元素,存到Set集合中;
注意:Map集合必须保证保证key唯一,作为key,必须重写hashCode方法和equals方法,以保证key唯一。
2.2、HashMap
数据结构:
JDK1.8之前:哈希表(数组+单向链表);
JDK1.8之后:哈希表(数组+单向链表+红黑树),
当链表长度超过阈值(8)时,链表将转换为红黑树。
链表:是一种物理存储单元上非连续,非顺序的存储结构。
1、思考:阈值为什么是8?
解:链表长度符合泊松分布,各个长度的命中概率依次递减,当长度为 8 的时候,概率仅为 0.00000006,这是一个小于千万分之一的概率,通常我们的 Map 里面是不会存储这么多的数据的,所以通常情况下,并不会发生从链表向红黑树的转换。
特点:查询快,元素无序,key不允许重复但可以为null,value可以重复。
底层分析:和HashSet底层相类似
参考文章链接:https://blog.youkuaiyun.com/weixin_39436556/article/details/118635569
2.3、LinkedHashMap
数据结构:
JDK1.8之前:哈希表(数组+双向链表);
JDK1.8之后:哈希表(数组+双向链表+红黑树),
当链表长度超过阈值(8)时,链表将转换为红黑树。
特点:查询快,元素有序,key不允许重复但可以为null,value可以重复。
底层分析:和LinkedHashSet底层相类似
2.4、HashTable
数据结构:哈希表
特点:查询快,元素无序,key不允许重复并且不可以为null,value可以重复。
底层分析:
HashTable和Vector一样是古老的集合,有遗留缺陷,在JDK1.2之后 被更先进的集合取代了;HashTable是线程安全的,速度慢,HashMap是线程不安全的,速度快
ps:Hashtable的子类Properties现在依然活跃,Properties集合是一个唯一和IO流结合的集合。
2.4、TreeMap
数据结构:红黑树
特点:查询快,元素有序,key不允许重复并且不可以为null,value可以重复。
底层分析:和TreeSet底层相类似