原文链接:https://blog.youkuaiyun.com/lkp1603645756/article/details/81264257
https://www.jianshu.com/p/939b8a672070
java 集合分为 Collection 和 Map 是所有集合的父接口
Collection 子接口有: List 和 Set 接口
List 接口下面分为:
ArrayList:
底层是数组,可以存储任意类型的数据,ArrayList是线程不安全的,非常适合用于对元素进行查找,效率非常高。
ArrayList分为无参数构造和有参构造方法,传入一个int类型的变量,相当于我们在使用arrayList的时候指定list的大小。
新长度是旧长度加上旧长度的0.5,所以ArrayList底层数组每次扩容的大小都是1.5倍。
删除是每次进行数组复制,然后让旧的elementData置为null进行垃圾回收
ArrayList的空 间浪费主要体现在在list列表的结尾预留一定的容量空间
总结:
1.在声明时尽量指定长度
2. ArrayList底层是数组,数组是适合查询的,因为数组每个元素的内存空间是固定的,每次查询时,只需要去查询对应位置
的内存空间,就可以很快找到相应的值。而数组不擅长的是添加和删除。试想,集合长度是100000,而我们在第2个位置
添加了一个元素,导致的结果是从第3个开始后面每一个元素都要往后串一个元素内存空间那么大的位置,删除刚好相反,
是向前串一个位置,这样的效率是很低的,元素越多,效率越低。而频繁的添加和删除,适用链表——LinkedList。
LinkedList:
数据存储是基于双向链表实现的,它允许插入所有元素,包括 null,同时,它是线程不安全的
LinkedList的空间花费则体现在它的每一个元素都需要消耗相当的空间
Vector:
线程安全的数组,加了synchronized关键字,性能最差
Set 接口: 存取无序、不允许存储重复的元素、只允许存储一个null值、没有角标,只能通过迭代器对象遍历访问
Set集合中所有的方法都是来来自于Collection集合,底层实现原理就是把HashMap的value置为null
HashSet集合:(类)底层使用哈希表结构(集合大小可变)
查询和添加不重复元素的效率比较快
LinkedHashSet集合:(类)底层使用了哈希表+链表+红黑二叉树的结构
存取元素有序、继承了HashSet类
查询和增删的效率都很快
TreeSet集合:(类)底层使用二叉树结构
查询的效率比较高,添加的效率比较低
添加的元素自按照制定的规则进行排序
1.自然排序 实现Comparable接口重写compareTo方法
2.比较器排序 实现Comparator接口重写compare方法
Set集合的弊端:不能精确访问集合中的元素
存取无序、不允许存储重复的元素、只允许存储一个null值、没有角标,只能通过迭代器对象遍历访问
Set集合中所有的方法都是来来自于Collection集合
Map接口:
HashMap:
它根据键的HashCode值存储数据,根据键可以直接获取它的值,具有很快的访问速度,遍历时,取得数据的顺序是
完全随机的。因为键对象不可以重复,所以HashMap最多只允许一条记录的键为Null,允许多条记录的值为Null,是非同步的
HashMap使用Key hashCode()和哈希算法来找出存储key-value对的索引。Entry存储在LinkedList中,所以如果存在entry,
它使用equals()方法来检查传递的key是否已经存在,如果存在,它会覆盖value,如果不存在,它会创建一个新的entry
然后保存。当我们通过传递key调用get方法时,它再次使用hashCode()来找到数组中的索引,然后使用equals()方法找出
正确的Entry,然后返回它的值
当添加一个元素(key-value)时,就首先计算元素key的hash值,以此确定插入数组中的位置,但是可能存在同一hash值的元素已经被放在数组同一位置了,这时就添加到同一hash值的元素的后面,他们在数组的同一位置,但是形成了链表,同一各链表上的Hash值是相同的,所以说数组存放的是链表。而当链表长度太长时,链表就转换为红黑树,这样大大提高了查找的效率。
当链表数组的容量超过初始容量的0.75时,再散列将链表数组扩大2倍,把原链表数组的搬移到新的数组中
LinkedHashMap:
是Hash表和链表的实现,并且依靠着双向链表保证了迭代顺序是插入的顺序。
LinkedHashMap和HashMap的存储结构基本相同,都是数组加链表。唯一不同的是,链表节点有两个指针,
分别是before和after,指向该结点的直接后继和直接前驱,再通过双向链表表头结点,
就可以实现从双向链表中的任意一个结点开始,很方便地访问它的前驱结点和后继结点。
LinkedHashMap采用的hash算法和HashMap相同,但它扩展了Entry(结点,用于存储key和value)。
LinkedHashMap中的Entry增加了 before 和 after两个指针,用于维护双向链表。
TreeMap :
实现了SotredMap接口,它是有序的集合。而且是一个红黑树结构,每个key-value都作为一个红黑树的节点。
如果在调用 TreeMap的构造函数时没有指定比较器,则根据key执行自然排序