Java迭代器

来源:互联网 发布:win8.1windows更新 编辑:程序博客网 时间:2024/06/01 18:26

概念:迭代器(iterator)是一种对象,只要拿到这个对象,使用迭代器就可以遍历这个对象的内部,它能够用来遍历标准模板库容器中的部分或全部元素,每个迭代器对象代表容器中的确定的地址。

java中常用的迭代方式
1、Iterator
(1)、Java中的Iterator功能比较简单,并且只能单向移动,
使用方法iterator()要求容器返回一个Iterator。第一次调用Iterator的next()方法时,它返回序列的第一个元素。

Package  java.util; public interface Iterator<E> {    boolean hasNext();//使用hasNext()检查序列中是否还有元素。     E next();//使用next()获得序列中的下一个元素    void remove();//使用remove()将迭代器新返回的元素删除}

(2)、讲到迭代器的时候就顺便把Iterable这个接口也做一下说明。
Iterable接口中只有一个iterator()方法,也就是返回一个迭代器。

import java.util.Iterator;public interface Iterable<T> {    Iterator<T> iterator();//返回一个迭代器}

(3)、其实大多数时候我们是用不到Iterable的,但是如果我们查看一下Collection接口,会发现它是实现了Iterable接口的。
(4)、我们常用的实现了该接口的类有: Collection, Deque, List, Queue, Set等。实现这个接口允许对象成为 Foreach 语句的目标。也就是说只有实现该接口,才可以通过Foreach语法遍历你的底层序列。如果我们自定义一个类实现了Iterable接口,那么它就可以用于foreach语句中。
(5)、下面写一个Iterator的基本例子

public class ArrayListDemo {    public static void main(String[] args) {        //list对象        List<String> listStrs =  new ArrayList<String>();        listStrs.add("java");        listStrs.add("c");        listStrs.add("jquery");        //List接口实现了Iterable接口        Iterator<String> iterList= listStrs.iterator();        while(iterList.hasNext()){            System.out.println(iterList.next());        }        //Set对象        Set<String> setStrs = new HashSet<String>();        setStrs.add("wang");        setStrs.add("zhang");        setStrs.add("deng");        //Set接口实现了Iterable接口        Iterator<String> iterSet= setStrs.iterator();        while(iterSet.hasNext()){            System.out.println(iterSet.next());        }        //Map对象        Map<String, String> mapStrs = new HashMap<String, String>();        mapStrs.put("1", "student");        mapStrs.put("2", "teacher");        //Map对象没有实现Iterable接口,但是mapStrs.entrySet()返回的是一个set        Iterator<Entry<String, String>> iterMap = mapStrs.entrySet().iterator();        while(iterMap.hasNext()){              Entry<String, String> strMap=(Entry<String, String>)iterMap.next();                System.out.println(strMap.getValue());          }      }}

当然,如果我们想双向移动,也就是可以从头和尾进行遍历,我们可以用针对不同接口的迭代器,例如针对list的迭代器ListIterator,该迭代器只能用于各种List类的访问。

2、foreach
(1)、foreach是jdk1.5新增的loop方法,可以用来遍历集合而不用知道集合的大小,格式如下:
for(variable var :collection){ statement; }
(2)、写一个基本例子:

public class ForEachDemo {    public static void main(String[] args) {        List<String> list = new ArrayList<String> ();        for(String str:list){              System.out.println(str);            }    }}

使用foreach的优势就是结构简单,不用关心容器的大小,直接遍历即可。
3、for循环
这种方式是最原始的的遍历容器的方式,缺点是遍历的时候需要知道容器的大小。

4、Iterator和for循环的比较
其实这个问题是要看需要遍历的容器决定的,不能直接拿来做比较,假如要比较的容器是list的实现类,ArrayList和LinkedList。
(1)、首先ArrayList内部是一种动态数组的数据结构,get(0)和get(1)这两个元素在物理上位置上也是相连的,随机获取元素的时间复杂度是o(1)。
(2)、LinkedList内部是一种链表的数据结构,随机获取元素的时间复杂度是o(n)。
(3)、因为在for循环中调用list.get(i)获取元素是一种随机访问,所以这个时候ArrayList效率要高很多,特别是当数量级特别大的时候。
(4)、在Iterator中next()方法,采用的即是顺序访问的方法,因此LinkedList中使用Iterator比较快。
使用for循环的方式如下:

public static void main(String[] args) {    // add elements    int size = 2000000;    List<String> list = new LinkedList<String>();    for (int i = 0; i < size; i++) {        list.add("Just some test data");    }    long startTime = System.currentTimeMillis();    for (int i = 0; i < size; i++) {        list.get(i);        if (i % 10000 == 0) {            System.out.println("query 10000 elements spend: "                    + (System.currentTimeMillis() - startTime));            startTime = System.currentTimeMillis();        }    }}

demo
如果换成Iterator:

public static void main(String[] args) {        // add elements        int size = 2000000;        List<String> list = new LinkedList<String>();        for (int i = 0; i < size; i++) {            list.add("Just some test data");        }        long startTime = System.currentTimeMillis();        Iterator<String> it = list.iterator();        int i = 0;        while (it.hasNext()) {            it.next();            ++i;            if (i % 10000 == 0) {                System.out.println("query 10000 elements spend: "                        + (System.currentTimeMillis() - startTime));                startTime = System.currentTimeMillis();            }        }    }

demo

0 0
原创粉丝点击