简体   繁体   English

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

[英]How to iterate over alternative elements using an 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());
}

The above code will iterate sequentially 1 through 6. Can we iterate the same list alternatively so that it will print 1, 3, 5 without changing the while loop? 上面的代码将按顺序迭代1到6.我们是否可以交替迭代相同的列表,以便在不更改while循环的情况下打印1, 3, 5

Create your own Iterator . 创建自己的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;
    }
}

making your code 制作你的代码

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

You only want to print the odd numbers? 你只想打印奇数? Filter the list with a stream: 使用流过滤列表:

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());
}

Edit: 编辑:

if you want to get every other element then using streams will be less appropriate, but you can still do it: 如果你想获得所有其他元素,那么使用流将不太合适,但你仍然可以这样做:

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());
}

I recommend daniu's solution. 我推荐daniu的解决方案。

A simple mechanism is to just use the index of the list items: 一个简单的机制是只使用列表项的索引:

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

And if you particularly want an iterator, just call iterator() instead of forEach . 如果你特别想要一个迭代器,只需调用iterator()而不是forEach

Yes, you can. 是的你可以。 Inside the while loop's body, check if the iterator has a next element, and if it does, advance the iterator again. 在while循环体内,检查迭代器是否有下一个元素,如果有,则再次推进迭代器。 This will cause the even elements not to be printed. 这将导致偶数元素不被打印。

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();
    }
}

I think that the java-8 way to do it would be something like this: 我认为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;
    }

}

And usage: 用法:

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

You could create an Iterator implementation that wraps an already existant iterator: 您可以创建一个包含已经存在的迭代器的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();
    }
} 

making your code the following: 使您的代码如下:

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());
}

Iterator implementation that wraps an already existing iterator. 包含已存在的迭代器的迭代Iterator实现。 It provides the logically correct definition of hasNext() method for alternate iterator as the hasNext() method should return true only if the alternate position number is present. 它为备用迭代器提供了对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;
            }
        }
    }

Create your own custom iterator from any underlying iterator: 从任何底层迭代器创建自己的自定义迭代器:

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();
    }
}

A very simple code goes like this: 一个非常简单的代码是这样的:

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;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM