LinkedList
- 集合底层实现的数据结构为双向链表
- 集合中元素允许为 null
- 允许存入重复的数据
- 中元素存放顺序为存入顺序。
- 是非线程安全的,如果想保证线程安全的前提下操作
- 可以使用 List list = Collections.synchronizedList(new LinkedList(…)) 来生成一个线程安全的LinkedList
ArrayList
- ArrayList就是数组列表,主要用来装载数据,当我们装载的是基本类型的数据int,long,boolean,short,byte…的时候我们只能存储他们对应的包装类
- 它的主要底层实现是数组Object[] elementData
1.7初始化的时候,调用this(10),直接容量为10;1.8默认走空数组,第一次add才默认为10
查询效率高,增删效率低,线程不安全。使用频率很高
增删很慢,你能说一下ArrayList在增删的时候是怎么做的么?主要说一下他为啥慢?
- index新增,也有直接新增的,在这之前他会有一步校验长度的判断ensureCapacityInternal,就是说如果长度不够,是需要扩容的
- 在扩容的时候,老版本的jdk和8以后的版本是有区别的,8之后的效率更高了,采用了位运算,右移一位,其实就是除以2这个操作
- 比如有下面这样一个数组我需要在index 5的位置去新增一个元素A,复制了一个数组,是从index 5的位置开始的,然后把它放在了index 5+1的位置
- 复制数组效率低
会初始化数组大小!但是List的大小没有变,因为list的大小是返回size的
线程安全版本的数组容器是Vector
LinkedList ArrayList区别
双向链表&Object数组
插入删除&随机查找
都是不同步的,不保证线程安全
内存空间占用,ArrayList在结尾预留容量空间,LinkedList每一个元素消耗更多的空间
//ArrayList实现线程安全
List<String> list = Collections.synchronizedList(new ArrayList<String>());
区别:
数据结构实现:arraylist是动态数组的数据结构实现,而linkedList是双向链表的数据结构实现
随机访问效率:arraylist效率高,因为linkedlist是线性的数据存储,需要移动指针从前往后一次查找
增加和删除效率:在非首尾的增加和删除,linkedlist效率更高,因为arraylist增删操作影响到数组其他数据的下标
所以在频繁读取集合中的元素使用arraylist,在插入和删除操作比较多时,推荐使用linkedlist
lists.add(list)和lists.add(new ArrayList<>(list))的区别
/第一种情况:
List<List<Integer>> res = new ArrayList<>();
List<Integer> row = new ArrayList<>();
for (int i = 1; i <= 3; i++) {
row.add(i);
res.add(row);
}
//结果:res: [[1,2,3],[1,2,3],[1,2,3]]
//只创建了两个对象,res和row,最后添加进res的是三个同样的对象row的引用。
//第二种情况:
for (int i = 1; i <= 3; i++) {
row.add(i);
res.add(new ArrayList<>(row));
}
//结果:res: [[1],[1,2],[1,2,3]]
//创建了5个对象,res,row以及row的三个不同时刻的拷贝。