Iterator、Iterable接口的使用及详解-阿里云开发者社区

开发者社区> developerguy> 正文

Iterator、Iterable接口的使用及详解

简介: Java集合类库将集合的接口与实现分离。同样的接口,可以有不同的实现。 Java集合类的基本接口是Collection接口。而Collection接口必须继承java.lang.Iterable接口。
+关注继续查看

Java集合类库将集合的接口与实现分离。同样的接口,可以有不同的实现。

Java集合类的基本接口是Collection接口。而Collection接口必须继承java.lang.Iterable接口。

以下图表示集合框架的接口,java.lang以及java.util两个包里的。其他部分可以从左向右看,比如Collection的Subinterfaces有List,Set以及Queue等。

package java.util;

/**
 * An iterator over a collection.  Iterator takes the place of Enumeration in
 * the Java collections framework.  Iterators differ from enumerations in two
 * ways: <ul>
 *    <li> Iterators allow the caller to remove elements from the
 *         underlying collection during the iteration with well-defined
 *          semantics.
 *    <li> Method names have been improved.
 * </ul><p>
 *
 * This interface is a member of the 
 * <a href="{@docRoot}/../technotes/guides/collections/index.html">
 * Java Collections Framework</a>.
 *
 * @author  Josh Bloch
 * @version %I%, %G%
 * @see Collection
 * @see ListIterator
 * @see Enumeration
 * @since 1.2
 */
public interface Iterator<E> {
    /**
     * Returns <tt>true</tt> if the iteration has more elements. (In other
     * words, returns <tt>true</tt> if <tt>next</tt> would return an element
     * rather than throwing an exception.)
     *
     * @return <tt>true</tt> if the iterator has more elements.
     */
    boolean hasNext();

    /**
     * Returns the next element (每一次迭代,the next element就是index为0的元素)in the iteration.
     *
     * @return the next element in the iteration.
     * @exception NoSuchElementException iteration has no more elements.
     */
    E next();

    /**
     * 
     * Removes from the underlying collection the last element returned by the
     * iterator (optional operation).  This method can be called only once per
     * call to <tt>next</tt>.  The behavior of an iterator is unspecified if
     * the underlying collection is modified while the iteration is in
     * progress in any way other than by calling this method.
     *
     * @exception UnsupportedOperationException if the <tt>remove</tt>
     *          operation is not supported by this Iterator.
     
     * @exception IllegalStateException if the <tt>next</tt> method has not
     *          yet been called, or the <tt>remove</tt> method has already
     *          been called after the last call to the <tt>next</tt>
     *          method.
     */
    void remove();
}

以下例子是利用了Iterator接口的着三个方法,实现遍历ArrayList<String>类型。
一开始迭代器在所有元素的左边,调用next()之后,迭代器移到第一个和第二个元素之间,next()方法返回迭代器刚刚经过的元素
hasNext()若返回True,则表明接下来还有元素,迭代器不在尾部。
remove()方法必须和next方法一起使用,功能是去除刚刚next方法返回的元素

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

public class ForEachDemo {
    public static void main(String... arg) {
        Collection<String> a = new ArrayList<String>();
        a.add("Bob");
        a.add("Alice");
        a.add("Lisy");

        Iterator<String> iterator = a.iterator();
        while (iterator.hasNext()) {
            String ele = iterator.next();
            System.out.println(ele);//Bob  Alice  Lisy    
        }
        System.out.println(a);//[Bob, Alice, Lisy]  
        iterator = a.iterator();
        iterator.next();
        iterator.remove();
        System.out.println(a);//[Alice, Lisy]  
    }
}  
package java.lang;

import java.util.Iterator;

/** Implementing this interface allows an object to be the target of
 *  the "foreach" statement.
 * @since 1.5
 */
public interface Iterable<T> {

    /**
     * Returns an iterator over a set of elements of type T.
     * 
     * @return an Iterator.
     */
    Iterator<T> iterator();
}

for-each循环可以与任何实现了Iterable接口的对象一起工作。
而java.util.Collection接口继承java.lang.Iterable,故标准类库中的任何集合都可以使用for-each循环。

Collection接口

此接口的方法

public interface Collection<E>{......}

  Modifier and Type Method and Description boolean add(E e)
Ensures that this collection contains the specified element (optional operation).
boolean addAll(Collection<? extends E> c)
Adds all of the elements in the specified collection to this collection (optional operation).
void clear()
Removes all of the elements from this collection (optional operation).
boolean contains(Object o)
Returns true if this collection contains the specified element.
boolean containsAll(Collection<?> c)
Returns true if this collection contains all of the elements in the specified collection.
boolean equals(Object o)
Compares the specified object with this collection for equality.
int hashCode()
Returns the hash code value for this collection.
boolean isEmpty()
Returns true if this collection contains no elements.
Iterator<E> iterator()
Returns an iterator over the elements in this collection.
boolean remove(Object o)
Removes a single instance of the specified element from this collection, if it is present (optional operation).
boolean removeAll(Collection<?> c)
Removes all of this collection's elements that are also contained in the specified collection (optional operation).
boolean retainAll(Collection<?> c)
Retains only the elements in this collection that are contained in the specified collection (optional operation).
int size()
Returns the number of elements in this collection.
Object[] toArray()
Returns an array containing all of the elements in this collection.
<T> T[] toArray(T[] a)
Returns an array containing all of the elements in this collection; the runtime type of the returned array is that of the specified array.

因为其中有一个返回值为Iterator<E>类型的iterator()方法,所以,java.util.Collection接口必须继承java.lang.Iterable接口

 

实现Collection接口的每一个类都要实现以上众多方法,但开发者自己实现很麻烦。所以java提供了AbstractCollection类来编写具体的类。

java.util
Interface Collection<E>

All Superinterfaces:
Iterable<E>
All Known Subinterfaces:
BeanContext, BeanContextServices, BlockingDeque<E>, BlockingQueue<E>, Deque<E>, List<E>, NavigableSet<E>, Queue<E>, Set<E>, SortedSet<E>
All Known Implementing Classes:
AbstractCollection, AbstractList, AbstractQueue, AbstractSequentialList, AbstractSet, ArrayBlockingQueue, ArrayDeque, ArrayList, AttributeList, BeanContextServicesSupport, BeanContextSupport, ConcurrentLinkedQueue, ConcurrentSkipListSet, CopyOnWriteArrayList, CopyOnWriteArraySet, DelayQueue, EnumSet, HashSet, JobStateReasons, LinkedBlockingDeque, LinkedBlockingQueue, LinkedHashSet, LinkedList, PriorityBlockingQueue, PriorityQueue, RoleList, RoleUnresolvedList, Stack, SynchronousQueue, TreeSet, Vector

Collection接口有三个常用的子接口,分别是List,Set,Queue。

http://blog.csdn.net/xujinsmile/article/details/8543544

为什么一定要去实现Iterable这个接口呢? 为什么不直接实现Iterator接口呢?

看一下JDK中的集合类,比如List一族或者Set一族,
都是继承了Iterable接口,但并不直接继承Iterator接口。
仔细想一下这么做是有道理的。因为Iterator接口的核心方法next()或者hasNext()
依赖于迭代器的当前迭代位置的。
如果Collection直接继承Iterator接口,势必导致集合对象中包含当前迭代位置的数据(指针)。
当集合在不同方法间被传递时,由于当前迭代位置不可预置,那么next()方法的结果会变成不可预知。
除非再为Iterator接口添加一个reset()方法,用来重置当前迭代位置。
但即时这样,Collection也只能同时存在一个当前迭代位置。
而Iterable则不然,每次调用都会返回一个从头开始计数的迭代器。
多个迭代器是互不干扰的。
http://www.cnblogs.com/highriver/archive/2011/07/27/2077913.html

import java.util.Iterator;

public class ForEachAPIDemo {
    public static void main(String[] args) throws Exception {
        Students students = new Students(10);
        for (Student student : students) {
            System.out.println(student.getSid() + ":" + student.getName());
        }
    }
}

// 支持for each迭代循环的学生集合类
class Students implements Iterable<Student> {
    // 存储所有学生类的数组
    private Student[] students;

    // 该构造函数可以生成指定大小的学生类变量数组,并初始化该学生类变量数组
    public Students(int size) {
        students = new Student[size];
        for (int i = 0; i < size; i++) {
            students[i] = new Student(String.valueOf(i), "学生" + String.valueOf(i));
        }
    }

    @Override
    public Iterator<Student> iterator() {
        return new StudentIterator();
    }

    // 实现Iterator接口的私有内部类,外界无法直接访问
    private class StudentIterator implements Iterator<Student> {
        // 当前迭代元素的下标
        private int index = 0;

        // 判断是否还有下一个元素,如果迭代到最后一个元素就返回false
        public boolean hasNext() {
            return index != students.length;
        }

        @Override
        public Student next() {
            return students[index++];
        }

        // 这里不支持,抛出不支持操作异常
        public void remove() {
            throw new UnsupportedOperationException();
        }
    }
}

class Student {
    private String sid;
    private String name;

    public Student(String sid, String name) {
        setSid(sid);
        setName(name);
    }

    public String getSid() {
        return sid;
    }

    public void setSid(String sid) {
        this.sid = sid;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Student{" +
                "sid='" + sid + '\'' +
                ", name='" + name + '\'' +
                '}';
    }
}

 

What hurts more? The pain of hard work or the pain of regret?

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
Java基础-23总结多线程,线程实现Runnable接口,线程名字获取和设置,线程控制,线程安全,同步线程
你需要的是什么,直接评论留言。 获取更多资源加微信公众号“Java帮帮” (是公众号,不是微信好友哦) 还有“Java帮帮”今日头条号,技术文章与新闻,每日更新,欢迎阅读 学习交流请加Java帮帮交流QQ群553841695 分享是一种美德,分享更快乐! 1:多线程(理解) (1)多线程:一个应用程序有多条执行路径 进程:正
2757 0
免费物流快递单号查询API接口及使用教程
因为需要对接物流/快递公司接口,时常会陷入选择服务商的困境,这次我整理了市场上几乎所有主流的物流/快递api接口,并且按照支持数量、接口的丰富性/稳定性/即时性,以及价格等因素,对各大服务商做了一个评级。
5319 0
阿里云服务器端口号设置
阿里云服务器初级使用者可能面临的问题之一. 使用tomcat或者其他服务器软件设置端口号后,比如 一些不是默认的, mysql的 3306, mssql的1433,有时候打不开网页, 原因是没有在ecs安全组去设置这个端口号. 解决: 点击ecs下网络和安全下的安全组 在弹出的安全组中,如果没有就新建安全组,然后点击配置规则 最后如上图点击添加...或快速创建.   have fun!  将编程看作是一门艺术,而不单单是个技术。
4478 0
如何判断自己使用的接口需要签约
说明:     很多同学可能不知道支付宝有些接口需要签约(我们称之为需签约接口),   有些不需要签约(我们称之为添加功能型接口)   应用如何创建:[url]https://openclub.alipay.
189 0
C#开发微信门户及应用(28)--微信“摇一摇&#183;周边”功能的使用和接口的实现
原文:C#开发微信门户及应用(28)--微信“摇一摇·周边”功能的使用和接口的实现 ”摇一摇周边“是微信提供的一种新的基于位置的连接方式。用户通过“摇一摇”的“周边”页卡,可以与线下商户进行互动,获得商户提供的个性化的服务。
1147 0
+关注
developerguy
A code cleanliness code farmers, A programmer concentrate on elegant design, A want to do with the product architect
1663
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
文娱运维技术
立即下载
《SaaS模式云原生数据仓库应用场景实践》
立即下载
《看见新力量:二》电子书
立即下载