List
2019-07-26 本文已影响0人
G_uest
继承结构
- Collection (interface)
- List (interface)
- ArrayList (class)
- LinkedList (class)
- Vector (class)
- List (interface)
List (interface) 有顺序、可以重复、允许多个null元素
对比
类 | 使用 | 说明 |
---|---|---|
ArrayList | 线程不安全 适合单线程访问时使用 |
动态对象数组实现,默认构造方法创建了一个空数组; 第一次添加元素,容量扩充为10,之后1.5倍扩充,增量为int类型向下取整; 查找速度快,增删速度慢 |
LinkedList | 线程不安全 适合单线程访问时使用 |
采用双向链表实现,插入,删除操作,性能高,但是查找速度慢 |
Vector 较少使用 |
线程安全 适合在多线程访问时使用 |
动态对象数组实现,默认构造方法创建了一个大小为10的对象数组; 扩充算法:当增量为0时,扩充为原来的2倍;当增量大于0时,扩充为 原来数组大小+增量; 不适合进行删除和插入操作;单线程使用时效率较低 |
解析
ArrayList使用动态对象数组实现,每次进行增加或删除操作,都会使操作元素后边的元素位置发生变化(向后或向前移位),所以增删元素相对较慢
但是因为有索引(数组下标)的存在,所以查找的速度较快,可以使用索引精确的对数据直接操作
LinkedList使用双向链表实现,对于增删操作可以直接改变节点指向,不需要移动元素,所以增删元素较快
但是在查找元素时,需要对链表进行遍历,这样查找效率就不如ArrayList速度快
ArrayList迭代异常
public static void main(String[] args) {
// 这里使用 ArrayList 举例,LinkedList结果相同
List list = new ArrayList();
list.add(1);
list.add(2);
list.add(3);
list.add(4);
// Iterator 迭代器实现迭代,迭代中对集合进行操作会报ConcurrentModificationException
// Iterator iterator = list.iterator();
// while (iterator.hasNext()) {
// Object object = iterator.next();
// System.out.println(object);
// if (object.equals(3)) {
// list.add(10);
// }
// }
// foreach 实现迭代,迭代中对集合进行操作会报ConcurrentModificationException
// for (Object object : list) {
// System.out.println(object);
// if (object.equals(3)) {
// list.add(10);
// }
// }
// System.out.println(list);
// for i 实现迭代
System.out.println("for i 实现迭代");
for (int i = 0; i < list.size(); i++) {
Object obj = list.get(i);
System.out.print(obj + " ");
if (obj.equals(3)) {
list.add(10);
}
}
System.out.println("\n" + list);
// ListIterator 列表迭代器实现迭代
System.out.println("ListIterator 列表迭代器实现迭代");
ListIterator lit = list.listIterator();
while(lit.hasNext()) {
Object value = lit.next();
System.out.print(value + " ");
if (value.equals(1)) {
lit.add("listitertor first add");
}
}
System.out.println("\n" + list);
}
输出
for i 实现迭代
1 2 3 4 10
[1, 2, 3, 4, 10]
ListIterator 列表迭代器实现迭代
1 2 3 4 10
[1, listitertor first add, 2, 3, 4, 10]
异常原因
在使用迭代器Iterator和foreach对集合迭代过程中,对集合进行增加操作(只有增加操作会报错),会报ConcurrentModificationException并发修改异常
但是正常for i不会报错,迭代器Iterator报错可以理解,但是foreach为什么会报错呢?
因为for-each循环隐式地创建了一个迭代器,但它没有向用户公开,因此我们无法修改集合中的项目
解决方案
使用List实现类提供的 ListIterator() 方法,ListIterator 是Iterator的子类,使用匿名内部类实现,其中有add方法,可以对集合进行增加操作。