List的实现
- ArrayList
ArrayList 是一个可改变大小的数组.当更多的元素加入到ArrayList中时,其大小将会动态地增长.内部的元素可以直接通过get与set方法进行访问,因为ArrayList本质上就是一个数组.当需要扩容的时候,ArrayList每次对size增长50%
- LinkedList
是一个双链表,在添加和删除元素时具有比ArrayList更好的性能.但在get与set方面弱于ArrayList.而 LinkedList 还实现了 Queue 接口,该接口比List提供了更多的方法,包括 offer(),peek(),poll()
- Vector
Vector 和ArrayList类似,但属于强同步类,Vector每次请求其大小的双倍空间
SynchronizedList和 Vector的区别
Vector是java.util包中的一个类。 SynchronizedList是java.util.Collections中的一个静态内部类。
可以通过Collections.synchronizedList(List list)方法来返回一个线程安全的List。
List<String> list = new ArrayList<String>();
List list2 = Collections.synchronizedList(list);
两者的区别
- Vector基本上使用同步方法来实现同步,而SynchronizedList里面实现的方法几乎都是使用同步代码块包上子类List的方法(如果包的是arraylist则包的是arraylist的方法)
- 两者的扩容机制不一样
- SynchronizedList没有对遍历的方法进行加锁!所以需要我们手动加锁
- Collections.synchronizedList() 可以指定加锁的对象!如果没指定那么默认锁的就是list
,vector强制锁的是list
通过Array.asList获得的List有何特点
- asList 得到的只是一个 Arrays 的内部类,一个原来数组的视图 List,因此如果对它进行增删操作会报错
- 用 ArrayList 的构造器可以将其转变成真正的 ArrayList
List<String> asList = Arrays.asList("ali","tesion");
ArrayList arrayList = new ArrayList(asList);
System.out.println(arrayList);
fail—fast 和 fail—safe的比较
直接粘贴H大的答案:
fail—fast 的特点:
在用迭代器遍历一个集合对象时,如果遍历过程中对集合对象的内容进行了修改(增加、删除、修改),
则会抛出ConcurrentModificationException。
如以下代码,会抛出ConcurrentModificationException:
for (Student stu : students) {
if (stu.getId() == 2)
students.remove(stu);
}
原理:迭代器在遍历时直接访问集合中的内容,并且在遍历过程中使用一个 modCount 变量。
集合在被遍历期间如果内容发生变化,就会改变modCount的值。每当迭代器使用hashNext()/next()遍历下一个元素之前,
都会检测modCount变量是否为expectedmodCount值,是的话就返回遍历;否则抛出异常,终止遍历。
注意:这里异常的抛出条件是检测到 modCount=expectedmodCount 这个条件。
如果集合发生变化时修改modCount值刚好又设置为了expectedmodCount值,则异常不会抛出。
因此,不能依赖于这个异常是否抛出而进行并发操作的编程,这个异常只建议用于检测并发修改的bug。
场景:java.util包下的集合类都是快速失败的,不能在多线程下发生并发修改(迭代过程中被修改)。
fail—safe的特点:
采用安全失败机制的集合容器,在遍历时不是直接在集合内容上访问的,而是先复制原有集合内容,在拷贝的集合上进行遍历。
原理:由于迭代时是对原集合的拷贝进行遍历,所以在遍历过程中对原集合所作的修改并不能被迭代器检测到,
所以不会触发ConcurrentModificationException。
缺点:基于拷贝内容的优点是避免了ConcurrentModificationException,但同样地,迭代器并不能访问到修改后的内容
,即:迭代器遍历的是开始遍历那一刻拿到的集合拷贝,在遍历期间原集合发生的修改迭代器是不知道的。
场景:java.util.concurrent包下的容器都是安全失败,可以在多线程下并发使用,并发修改。
ConcurrentHashMap, CopyOnWriteArrayList, CopyOnWriteArraySet都是符合fail—safe的
terator和ListIterator之间有什么区别
- Iterator可用于遍历Set、List,ListIterator只可用于List。
- Iterator只能向后遍历[next(), hasNext()],ListIterator可向前或向后遍历[previous(),
hasPrevious()]。 - ListIterator实现了Iterator的接口,并增加了 ①add()方法,可向List添加对象 ②set()方
法,可修改对象 ③定位索引位置,nextIndex(), previousIndex(