数组:连续的、可以重复的、固定大小、空间换时间
便于查询O(1):可以根据数组的下标直接查询
不便于插入删除O(n):插入删除元素,后边的元素都要移动,降低效率
链表:像链条一样,a->b->c 可以连续也可以不可连续,一般是不连续,没有固定大小,时间换取空间
便于插入删除O(1):插入删除元素,直接改变指针的指向的元素即可
不便于查询O(n):查询元素,需要一个节点一个节点的找,因为是无序的
红黑树(jdk1.8后):插入、删除、查询 时间 ,在最坏的情况有最好的解决方法
10
8 15
6 9 11 16
小的放左边,大的放右边 节点为红,子节点为黑
所谓有序和无序,不是指集合中的排序,而是是否按照元素的添加顺序来存储对象
-----------map-----------------
无序、key不可重复,值可重复,以键值对的形式存取
底层数据结构:数组
int a[][]=new Array[行][列] map是固定大小的,元素可以更换
一、Hashmap
底层数据结构:数组、链表、红黑树
性质:
无序、可重复、可以有空键值对
线程不安全(不同步)
默认的数组大小:16
加载因子:0.75
什么时候扩充数组: 当数组大小大于 160.75=12 时
扩充算法:当前数组大小<<1(相当于2)
扩充数组会使哈希表重新计算元素的位置,如果多次扩充会降低效率
数组分组:分组算法:哈希算法:hashcode %(数组长度-1)
hashmap插入元素的时候
1、数组+链表
根据key的hashcode计算hash值找到元素的位置,如果该位置没有元素,直接插入,如果有元素在,则使用链表的形式,插入到头部
2、数组+红黑树:当链表长度>8
当有元素存在,并且该位置的链表长度>8,使用红黑树来存储
二、hashtable(jdk1.0)
底层数据结构:数组+链表
性质:
线程安全(同步),因为每个方法都有synchronize定义 这也就是为什么有hashmap还要有hashtable
默认额加载因子:0.75
默认数组长度:11
什么时候扩充数组:11*0.75
扩充算法:当前数组大小<<1 +1(*2+1)
三、LinkedHashMap 是hashmap的子类
底层数据结构:数组、链表、红黑树
hashmap的有序性不是恒久不变的, 使用LinkedHashMap的双向链表来维护hashmap的有序性,只有这个是有序的
四、Treemap
底层数据结构:数组、链表、红黑树
和hashmap类似 但是内部的实现厚实用红黑树来实现
四者使用的情况
HashMap 是线程不安全的哈希表,用于单线程
LinkedHashMap:是一个维持双向链表,是一个有序的Map,怎么put的进去的输出时怎么取出,FIFO的顺序
TreeMap: 在需要排序的时候使用,在一个map放入很多数据,需要按照什么规则排序显示的时候。
hashtable是线程安全的,用于多线程,方法用synchronize修饰
------------–list-----------------------------
有序的,所以可以控制插入元素的位置
可以重复的,
因为list类似 【数组】,可以使用索引的方法来查询
只能容纳单个不同类型的对象组成的表,而不是键值对存取
可以有null元素
一、ArrayList
底层的数据结构:数组
重复、有序、线程不安全(不同步)
特点:
便于查询:可以通过下标直接查询
不便于插入删除:每次插入删除元素,后面的元素都要移动
二、LinkedList
底层数据结构:链表(双向链表)
每个节点包含三个信息:上个 自己 下个
特点:
便于插入删除:直接改变链表指针的指向元素
不便于查询:一个个的查找,效率低
三、vector
底层数据结构:数组
有序、可重复
线程安全
内部实现和ArrayList相同
------------set---------------------
不能重复、无序
底层数据结构:数组、链表、红黑树
和list的根本区别:
list以数组为底层实现
set以hashmap底层实现
一、HashSet
以hashmap底层实现
无序、不可重复
不可重复:根据hashcode和equal方法来保证元素的唯一性
二、LinkedHashSet
HashSet的子类
和hashset的区别
元素按照顺序排列顺序
取出元素的顺序和插入元素的顺序相同,使用LinkedHashSet代替hashset
linkedhashset内部使用linkedhashmap实现,因为hashset的底层实现就是hashmap
线程不安全(不同步)
只有这个是有序的
三、treeset
有序的
内部实现:红黑树 也就是treemap
不可重复 不能为null
重写comparator方法确定元素大小,进而升序排序