集合类的遍历:
1.使用Iterator接口
调用Collection集合子类的Iterator方法取得内置的迭代器,使得以下输出格式
//取得集合迭代器
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()){
System.out.println(iterator.next());
}
Collection接口下的子类都可以使用
2.双向迭代接口ListInterator—List接口支持,Set不支持
hasPrevious():判断是否有上一个元素
previous():取得上一个元素
ListIterator<String> listIterator =
list.listIterator();
while (listIterator.hasNext()){
System.out.print(listIterator.next()+" ");
}
System.out.println();
while (listIterator.hasPrevious()){
System.out.print(listIterator.previous()+" ");
}
3.Enumeration(JDK1.0)枚举输出—只有Vector支持
Vector<String> vector = new Vector<>();
vector.add("a");
vector.add("b");
//elements()取得Enumeration接口对象
java.util.Enumeration<String> enumeration = vector.elements();
while (enumeration.hasMoreElements()){
System.out.println(enumeration.nextElement());
}
4.for—each输出
能使用for-each输出的本质在于各个集合都内置了迭代器。
fail-fast机制:快速失败策略
遍历集合时,伴随修改操作就会出现(并发修改异常)
本质:int modCount变量
出现原因:每次使用add()/remove()方法时,就会modCount++;
进入iterator()内部可以看到
private class Itr implements Iterator<E> {
int cursor; // index of next element to return
int lastRet = -1; // index of last element returned; -1 if no such
int expectedModCount = modCount;
当遍历集合取得集合的迭代器时,会有expectedModcount=modCount;
遍历时会调用next(),在next()方法中会调用checkForCoModification(), 此方法中会检查expectedModcount=modCount;是否相等,不相等会报出ConcurrentModificationException:
final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
所以当我们遍历一个集合时,若在遍历途中修改元素下一次进入next()方法时就会检查modCount 与expectedModCount是否形同,不相同,自然就会报ConcurrentModificationException
快速失败策略保证了所有用户在进行迭代遍历集合时,拿到的数据一定是最 新的数据(避免”脏读“产生)
那么如何解决fail-fast:
集合遍历时不要修改(增,删)
使用迭代器内部的方法修改(快照删除,迭代遍历输出后就会看到删除了)
使用fail-safe集合:java.util包下除TreeMap以外的所有集合,juc包下的集合(ConcurrentHashMap、CopyonWriteArrayList)都属于fail-safe