如何使用迭代器迭代替代元素?

时间:2018-05-14 12:05:12

标签: java iterator

List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6);
Iterator<Integer> it = list.iterator();
while (it.hasNext()) {
    System.out.println(it.next());
}

上面的代码将按顺序迭代1到6.我们可以交替迭代相同的列表,以便在不更改while循环的情况下打印1, 3, 5吗?

9 个答案:

答案 0 :(得分:12)

创建自己的Iterator

class SkippingIterator<T> implements Iterator<T> {
    private List<T> list;
    private currentPosition;
    private int skipBy;
    public SkippingIterator(List<T> l) {
        this(l, 2);
    }
    public SkippingIterator(List<T> l, int skip) {
        this(l, skipBy, 0);
    }
    public SkippingIterator(List<T> l, int skip, int startPosition) {
        list = l;
        skipBy = skip;
        currentPosition = startPosition;
    }
    public boolean hasNext() {
        return currentPosition < list.size();
    }
    public T next() {
        T result = list.get(currentPosition);
        currentPosition += skip;
        return result;
    }
}

制作代码

List<Integer> list = Arrays.asList(1,2,3,4,5,6);
Iterator it = new SkippingIterator<>(list);
while(it.hasNext()){
    System.out.println(it.next());
}

答案 1 :(得分:7)

你只想打印奇数?使用流过滤列表:

List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6);
Iterator<Integer> it = list.stream().filter(x -> x % 2 == 1).iterator();
while (it.hasNext()) {
    System.out.println(it.next());
}

编辑:

如果你想获得所有其他元素,那么使用流将不太合适,但你仍然可以这样做:

List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6);
int limit = list.size() / 2 - (1 - list.size() % 2);
Iterator<Integer> it = IntStream.iterate(0, x -> x + 2).limit(limit).map(list::get).iterator();
while (it.hasNext()) {
    System.out.println(it.next());
}

我推荐daniu的解决方案。

答案 2 :(得分:5)

是的,你可以。在while循环体内,检查迭代器是否有下一个元素,如果有,则再次推进迭代器。这将导致不打印偶数元素。

List<Integer> list=Arrays.asList(1,2,3,4,5,6);
Iterator it=list.iterator();
while (it.hasNext()){
    System.out.println(it.next());
    if (it.hasNext()) {
        it.next();
    }
}

答案 3 :(得分:5)

一个简单的机制就是使用列表项的索引:

IntStream.range(0, list.size())
    .filter(i -> i % 2 == 0)
    .mapToObj(list::get)
    .forEach(System.out::println);

如果你特别想要一个迭代器,只需拨打iterator()而不是forEach

答案 4 :(得分:4)

我认为java-8的方法就是这样:

class Skipping extends AbstractSpliterator<Integer> {

    private List<Integer> list;
    private int index = 0;

    public Skipping(List<Integer> list) {
        super(list.size() / 2, 0);
        this.list = new ArrayList<>(list);
    }

    @Override
    public boolean tryAdvance(Consumer<? super Integer> action) {
        if (index != list.size()) {
            if (index % 2 == 0) {
                action.accept(list.get(index++));
            }
            ++index;
            return true;
        }
        return false;
    }

}

用法:

List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6);
Iterator<Integer> iter = StreamSupport.stream(new Skipping(list), false).iterator();

答案 5 :(得分:1)

您可以创建一个包含已经存在的迭代器的Iterator实现:

class IteratorWrapper<T> implements Iterator<T> {
    private final Iterator<? extends T> iterator;

    public IteratorWrapper(Iterator<? extends T> iterator){
        this.iterator = iterator;
    }

    public boolean hasNext(){
        return iterator.hasNext();
    }

    public T next(){
        final T next = iterator.next();
        if(iterator.hasNext()){
            iterator.next();
        }
        return next;
    }

    public void remove(){
        iterator.remove();
    }
} 

使您的代码如下:

List<Integer> list = Arrays.asList(1,2,3,4,5,6);
Iterator<Iterator> it = new IteratorWrapper<>(list.iterator());
while(it.hasNext()){
    System.out.println(it.next());
}

答案 6 :(得分:1)

Iterator实现,该实现包装了一个已经存在的迭代器。它为备用迭代器提供了hasNext()方法的逻辑正确定义,因为hasNext()方法仅在存在备用位置编号时才应返回true。

    import java.util.Iterator;

    public class AlternateIterator<T> implements Iterator<T>{

        private T next;
        private Iterator<T> it;

        public AlternateIterator(Iterator<T> it) {
            this.it = it;
            next = null;
        }
        // Logically hasNext() of this iterator should return true only if it has a valid alternate element present.
        @Override
        public boolean hasNext() {
            if(next != null) {
                return true;
            }
            if(it.hasNext()) {
                it.next();
                if(it.hasNext()) {
                    next = it.next();
                    return true;
                }
            }
            return false;
        }

        @Override
        public T next() {
            if(next != null) {
                T temp = next;
                next = null;
                return temp;
            }
            else {
                if(hasNext())
                    return next();
                else
                    return null;
            }
        }
    }

答案 7 :(得分:0)

从任何底层迭代器创建自己的自定义迭代器:

class TwoStepsAtOnceIterator<E> implements Iterator<E> {
    private Iterator<E> internal;
    public TwoStepsAtOnceIterator(Iterator<E> it) {
      internal = it;
    }
    public boolean hasNext() {
      return internal.hasNext();
    }
    public E next() {
      // problem not specified when underlying sequence has odd number of elements
      internal.next();
      return internal.next();
    }
    public void remove() {
      throw new UnsupportedOperationException();
    }
}

答案 8 :(得分:-1)

一个非常简单的代码如下:

List<Integer> list = Arrays.asList(1,2,3,4,5,6);
Iterator it = list.iterator();
while(it.hasNext()){
   static int i=0;
    if(i%2==0){
    System.out.println(it.next());
     }
     i+=1;
}