[转载]Java迭代器(iterator详解以及和for循环的区别)

Java迭代器(iterator详解以及和for循环的区别)

以为有用的话,欢迎一块儿讨论相互学习~

个人微博个人github个人B站

前言

  • 迭代器是一种模式、详细可见其设计模式,可使得序列类型的数据结构的遍历行为与被遍历的对象分离,即咱们无需关心该序列的底层结构是什么样子的。只要拿到这个对象,使用迭代器就能够遍历这个对象的内部
  • Iterable 实现这个接口的集合对象支持迭代,是能够迭代的。实现了这个能够配合foreach使用~
  • Iterator 迭代器,提供迭代机制的对象,具体如何迭代是这个Iterator接口规范的。
//Iterable JDK源码
//能够经过成员内部类,方法内部类,甚至匿名内部类去实现Iterator

public interface Iterable<T>
{

    Iterator<T> iterator();
  • Iterable还有一个默认的方法forEach()
  • 而Iterator接口:包含三个方法:hasNext,next,remove、remove通常不多用到.
public interface Iterator<E> {


    boolean hasNext();    //每次next以前,先调用此方法探测是否迭代到终点

    E next();            //返回当前迭代元素 ,同时,迭代游标后移


     /*删除最近一次已近迭代出出去的那个元素。
     只有当next执行完后,才能调用remove函数。
     好比你要删除第一个元素,不能直接调用 remove()   而要先next一下( );
     在没有先调用next 就调用remove方法是会抛出异常的。
     这个和MySQL中的ResultSet很相似
    */
    void remove()
    {
        throw new UnsupportedOperationException("remove");
    }

Note

  • 迭代出来的元素都是原来集合元素的拷贝。
  • Java集合中保存的元素实质是对象的引用,而非对象自己。
  • 迭代出的对象也是引用的拷贝,结果仍是引用。那么若是集合中保存的元素是可变类型的,那么能够经过迭代出的元素修改原集合中的对象。
import java.util.ArrayList;
import java.util.Iterator;

public class test {
    public static void main(String[] args) {
        ArrayList<Person> array = new ArrayList<Person>();

        Person p1 = new Person("Tom1");
        Person p2 = new Person("Tom2");
        Person p3 = new Person("Tom3");
        Person p4 = new Person("Tom4");

        array.add(p1);
        array.add(p2);
        array.add(p3);
        array.add(p4);

        Iterator<Person> iterator = array.iterator();

        for (Person pp : array){
            System.out.println(pp.getName());
        }

        System.out.println("\r\n" + "-----利用Lambda表达式的foreach-----" + "\r\n");
        array.forEach(obj -> System.out.println(obj.getName()));


        System.out.println("\r\n" + "-----利用for循环-----" + "\r\n");
        for(Person p : array){
            p.setName("wang");
        }

        while(iterator.hasNext()){
            System.out.println(iterator.next().getName()); //输出的是wang,而不是tom
        }



    }
}

Map遍历也是同样的~

public static void main(String[] args) {
        Map map = new HashMap();
        for(int i = 0; i < 10; i ++){
            map.put(i, String.valueOf("map" + i));
        }
        Iterator iterMap = map.entrySet().iterator();
        while(iterMap.hasNext()){
            Map.Entry strMap = (Map.Entry)iterMap.next();
            System.out.println("key为:" + strMap.getKey() +
                    ", value为:" + strMap.getValue());
        }
    }

那么当Iterator迭代访问Collection集合中元素时,Collection的元素不能改变(多个线程的修改),只有经过Iterator的remove()方法删除上一次next()方法返回集合才能够。这样会引起ModificationException异常,即fail-fast机制java

//建立集合,添加元素和上述同样      
        Iterator<Person> iterator = array.iterator();

      while(iterator.hasNext()){
         String name = iterator.next().getName();
         System.out.println(name);
         if(name.equals("Tom3")){
             //array.remove(name);  不推荐这种方式
             iterator.remove();
         }
      }

Iterator与泛型搭配:

  • Iterator对集合类中的任何一个实现类,均可以返回这样一个Iterator对象。能够适用于任何一个类。
  • 由于集合类(List和Set等)能够装入的对象的类型是不肯定的,从集合中取出时都是Object类型,用时都须要进行强制转化,这样会很麻烦,用上泛型,就是提早告诉集合肯定要装入集合的类型,这样就能够直接使用而不用显示类型转换.很是方便.

foreach和Iterator的关系:

  • for each以用来处理集合中的每一个元素而不用考虑集合定下标。就是为了让用Iterator简单。可是删除的时候,区别就是在remove,循环中调用集合remove会致使原集合变化致使错误,而应该用迭代器的remove方法。

使用for循环仍是迭代器Iterator对比

  • 采用ArrayList对随机访问比较快,而for循环中的get()方法,采用的便是随机访问的方法,所以在ArrayList里,for循环较快
  • 采用LinkedList则是顺序访问比较快,iterator中的next()方法,采用的便是顺序访问的方法,所以在LinkedList里,使用iterator较快
  • 从数据结构角度分析,for循环适合访问顺序结构,能够根据下标快速获取指定元素.而Iterator 适合访问链式结构,由于迭代器是经过next()和Pre()来定位的.能够访问没有顺序的集合.
  • 而使用 Iterator 的好处在于可使用相同方式去遍历集合中元素,而不用考虑集合类的内部实现(只要它实现了 java.lang.Iterable 接口),若是使用 Iterator 来遍历集合中元素,一旦再也不使用 List 转而使用 Set 来组织数据,那遍历元素的代码不用作任何修改,若是使用 for 来遍历,那全部遍历此集合的算法都得作相应调整,由于List有序,Set无序,结构不一样,他们的访问算法也不同.(仍是说明了一点遍历和集合自己分离了)
相关文章
相关标签/搜索