Iterable Iterator Java

Iterator接口

interface Iterator<E>{
    /**
    * Returns ture if the iteration has more elements.
    * in other words, returns true if java.util.Iterator.next()would return an element rather than throwing an exception.
    * @return ture if the iteration has more elements.
    */
    boolean hasNext();

    /**
    * returns the next element in the iteration.
    * @return the next element in the iteration
    * @throws NoSuchElementException if the iteration has no more elements
    */
    E next();


    /**
    * 从底层集合中删除此迭代器返回的最后一个元素(可选操作)。
    * 每次调用{@link #next}时,此方法只能调用一次。 如果在迭代正在以除调用此方法之外的任何方式进行时修改底层集合,则迭代器的行为是未指定的。
    * 大概就是快速失败(fast-fail)
    */
    default void remove(){
        throw new UnsupportedOperationException("remove");
    }


    /**
    * 对每个剩余元素执行给定的操作,直到所有元素都已处理或操作抛出异常。 
    * 操作抛出的异常依赖于调用者。
    */
    default void forEachRemaining(Consumer<? super E> action){
        Objects.requireNonNull(action);
        while(hasNext())
            action.accept(next());
    }
}

迭代器模式的结构

  • 抽象容器:一般是一个接口,提供一个iterator()方法,如Java中的Collection接口,List接口,Set接口
  • 具体容器:就是抽象容器的具体实现类,如List接口的有序列表实现ArrayList,List接口的链表实现LinkedList,Set接口的哈希列表实现HashSet
  • 抽象迭代器:定义遍历元素所需要的方法,一般有3个:取得第一个元素的方法first(), 取得下一个元素的方法next(), 判断是否遍历结束的方法hasNext(),移除当前对象的方法remove()
  • 迭代器实现:实现迭代器接口中定义的方法,完成集合的迭代。

Iterable接口

java.lang.Iterable
public interface Iterable<T> {
    /**
    * 返回一个iterator
    * @Return an Iterator
    */
    Iterator<T> iterator();

    default void forEach(Consumer<? super ?> action){
        Objects.requireNonNull(action);
        for(T t : this){
            action.accept();
        }
    }

    default Spliterator<T> spliterator(){
        return Spliterators.spliteratorUnknownSize(iterator(), 0);
    }
}

Java Iterator and Iterable
trying to understand Java Iterator and Iterable interfaces

class MyClass implements Iterable<String>{
    public String[] a = null;
    public MyClass(String[] arr){
        a = arr;
    }

    public MyClassIterator iterator(){
        return new MyClassIterator(this);
    }

    public class MyClassIterator implements Iterator<String>{
        private MyClass myclass = null;
        private int count = 0;
        public MyClassIterator(MyClass m){
            myclass = m;
        }

        public boolean hasNext(){
            if(count < myclass.a.length){
                return true;
            }else{
                return false;
            }
        }
        public String next(){
            int t = count;
            count++;
            return myclass.a[t];
        }

        public void remove(){
            throw new UnsupportedOperationException();
        }
    }

}

上面的代码是可以工作的,是否可以写成:

Myclass implements Iterable<String>, Iterator<String>{}

或者把MyClassIterator 放到MyClass外面:

class MyClass implements Iterable<String>{
    public String[] a=null;
    public MyClass(String[] arr){
        a=arr;  
    }
    public MyClassIterator iterator(){
        return new MyClassIterator(this);
    }
}

public class MyClassIterator implements Iterator<String>{
        private MyClass myclass=null;
        private int count=0;
        public MyClassIterator(MyClass m){
            myclass=m;  
        }

        public boolean hasNext(){
            if(count<myclass.a.length){
                return true;
            }else{
                return false;

            }
        }
        public String next(){
            int t = count;
            count++;
            return myclass.a[t];
        }

        public void remove(){
            throw new UnsupportedOperationException();
        }
    }   

哪个更好呢?
Answer1:

You should almost never implement both Iterable and Iterator in the same class. They do different things. An iterator is naturally stateful - as you iterate using it, it has to update its view of the world. An iterable, however, only needs to be able to create new iterators. In particular, you could have several iterators working over the same original iterable at the same time.

Your current approach is pretty much okay - there are aspects of the implementation I'd change, but it's fine in terms of the separation of responsibilities.

你几乎不应该在同一个类中实现IterableIterator,他们做的事情是不同的。iterator是有状态的,当你用它迭代时,它必须更新。然而,一个Iterable只需要能够创建新的迭代器。尤其是,你可以有多个iterators同时工作在相同的original iterable上.
你现在的方法是对的。

建议把MyClassIterator作为嵌套类,private static final class
为什么 要是static的呢?
because you are not using the implicit reference to an instance of the outer class, so why not make it static?
因为没有用隐藏的引用到一个外围类的实例上。(但一般应该用个隐式的引用到外围类上?。。)

Answer2:

You were on track with your first try. MyClass only needs to implement Iterable<String>, which in turn requires you to provide an Iterator<String> implementation to return from Iterable<String>.iterator().

There's no need to put the MyClassIterator outside of MyClass because in most cases you will never even need to directly use the Iterator<String> (it's used implicitly by the for .. in .. syntax on Iterable<String>s), and in all other cases the interface is sufficient unless you actually add additional behavior to the implementation (which you likely won't ever need to do).

MyClass只需要implements Iterable<String>,反过来,你需要提供一个Iterator<String>的实现来返回Iterable<String>.iterator()
这是被隐式使用的(for … in …语法是基于Iterable<String>的),在其他情况下,interface就足够了,除非你想添加额外的行为来实现(一般你不会这么做)。
看一下我写的代码和注释:

import java.util.Iterator;
class MyClass implements Iterable<String>{
    public String[] a = null; //如果可以的话最好设置为final
    public MyClass(String[] arr){
        a = arr; // 也许应该copy这个arr,以免外部发生改变
    }
    // 接口可以放这里,外界不需要知道你的具体实现
    public Iterator<String> iterator(){
        //no point implementing a whole class for something only used once

        return new Iterator<String>(){
            //no need to have constructor which takes MyCLass,
            // 非静态内部类可以访问实例成员
            private int count = 0;
            public boolean hasNext(){
                return count < a.length;
            }
            public String next(){
                return a[count++];
            }
            public void remove(){
                throw new UnsupportedPerationException();
            }
        }
    }
}

Collection也是Iterable的

public interface Collection<E> extends Iterable<E>{
    int size();
    boolean isEmpty();
    boolean contains(Object o);
    Iterator<E> iterator();
    Object[] toArray();
    <T> T[] roArray(T[] a);
    boolean add(E e);
    boolean remove(Object o);
    boolean containsAll(Collection<?> c);
    boolean addAll(Collection<? extends E> c);
    boolean removeAll(Collection<?> c);
    ...
    boolean retainAll(Collection<?> c);
    void clear();
    boolean equals(Object o);
    int hashCode();
    ...
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值