迭java代器中怎么拿到循环次数 java迭代器输出_迭代

Iterable<T>:迭代器接口(就是为了遍历集合)@since1.5

迭java代器中怎么拿到循环次数 java迭代器输出_迭代_02

Iterator<T>iterator();(取的集合的迭代器,JDK1.5之前直接写在collection接口中)

Iterator<T>接口的方法    Scanner也是Iterator接口的实现类

迭java代器中怎么拿到循环次数 java迭代器输出_迭代_03

迭代器:为了遍历集合而生。—迭代器模式

Collection接口中也有Iterator<T>iterator();方法

Iterator<T>接口的两个核心方法 :

      boolean hasNext();  判断是否还有元素

      E next();取得下一个元素

 

之前用for循环遍历,能遍历是因为各个集合都有内置的迭代器

public class IteratorTest{
	public static void main(String[] args){
		List<String> list=new ArrayList<>();
		list.add("hello");
		list.add("world");
		list.add("hello");
		list.add("java");
		System.out.println(list);
		Iterator iterator=list.iterator();
		while(iterator.hasNext()){
			System.out.println(iterator.next());
		}
	}
}

结果:

迭java代器中怎么拿到循环次数 java迭代器输出_迭代_04

1、迭代输出Iterator—只能从前向后输出—Collection接口提供(只有set和list有Iterator对象,map没有)

调用Collection集合子类的Iterator方法取得内置的迭代器(Iterator iterator=list.iterator();),使用以下输出格式

while(iterator.hasNext()){

    System.out.println(iterator.next());

}

 

2、双向迭代接口listIterator—List接口提供,set不支持

除了由hashNext()方法和next()方法以外,还有

hasPrevious():判断是否由上一个元素

pervious():取得上一个元素

ListIterator iterator=list.listIterator();
while(iterator.hasPrevious()){
    System.out.println(iterator.previous());
}

运行结果为空:要想使用从后往前遍历输出,首先至少要从前向后遍历一个次能使用

3、Enumeration(JDK1.0)枚举输出—Vector类支持

hasMoreElements():判断是否由下一个元素

nextElements():取得下一个元素

Vector<String> vector= new Vector<>();
vector.add("hello");
vector.add("world");
vector.add("hello");
vector.add("java");
System.out.println(vector);
Enumeration<String> enumeration=vector.elements();
while(enumeration.hasMoreElements()){
    System.out.println(enumeration.nextElement());
}

4、for-eash输出:用for-eash输出的本质,各个集合都内置了迭代器,还是调用了迭代器
 

for(String s:vector){
    System.out.println(s);//其余代码同上
}

Fail-fast机制

Collections中的方法

public static <T> boolean addAll(Collection<?superT>c,T...elements)

java.util.ConcurrentModificationException发生在Collection集合使用迭代器遍历时,使用了集合类提供的修改集合内容方法报错,而如果使用iterator迭代器的remove()方法不会出现此错误。

ArrayList的内部类中itr中

final void checkForComodification(){
    if(modCount!=expectedModCount)
        Throw new ConcurrentModificationException();
}

Collection中的modCount表示当前集合表示当前集合修改的次数(在并发的场景下,用户在遍历时,修改内容,有一个值告知别人改了没改,保证用户不会脏读)

脏读:我现在看到的数据不是最新的

modCount保证了用户看到的值一定是当前集合的最新值

expectedModCount迭代器中记录当前集合的修改次数

当取得集合迭代器时(即调用list.iterator()---->return new Itr()-->expectedModCount=modCount):expectedModCount=modCount,换言之,迭代器就是当前集合的副本,拷贝

迭java代器中怎么拿到循环次数 java迭代器输出_System_05

 

public static void main(String[] args){
    List<String> list = new ArrayList<>();
    Collections.addAll(list,"A","B","c","D","E","B");
    //modCount=6
    Iterator<String> iterator = list.iterator();
    //取得集合迭代器(取得当前集合的副本)
    //expectedModCount=modCount=6
    while(iterator.hasNext()){
        String str=iterator.next();
        //next()调用checkForComodification()检查副本中的expectedModCount是否等于集合的modCount
        //每当在遍历时做了变化,下次遍历时一定会出错,告诉当前的集合可能已经被修改,你看到的值不一是最新的
        if(str.equals("B")){
            list.remove("B");
            //modCount=modCount+1=7
            continue;
        }   
    System.out.println(str);
    }
    System.out.println(list);
}

在有迭代的情况下,list.remove("B")会出错。

快速失败策略保证了所有用户在进行迭代遍历集合是,拿到的数据一定是最新的数据(避免脏读产生)

Fail-safe:不产生ConcurrentModificationException异常

juc包下的所有线程安全集合:ArrayList、Vector、 LinkedList都在Java.util包下

Juc:并发安全包(CopyOnWriteArrayList,concurrentHashMap??)

 

以后再迭代器遍历时,不要修改集合内容

 

while(iterator.hasNext()){
    String str=iterator.next();
    //next()调用checkForComodification()检查副本中的expectedModCount是否等于集合的modCount
    //每当在遍历时做了变化,下次遍历时一定会出错,告诉当前的集合可能已经被修改,你看到的值不一是最新的
    if(str.equals("B")){
        iterator.remove();
        //modCount=modCount+1=7
        continue;
    }
    System.out.println(str);
}

为什么iterator.remove();不报错??

因为:

迭java代器中怎么拿到循环次数 java迭代器输出_System_06