在Java中使用一系列整数获取迭代器的最短方法

时间:2008-12-16 11:16:22

标签: java iterator

在Java中使用一系列整数获取Iterator的最短路径是什么?换句话说,实现以下内容:

/** 
* Returns an Iterator over the integers from first to first+count.
*/
Iterator<Integer> iterator(Integer first, Integer count);

这样的东西
(first..first+count).iterator()

7 个答案:

答案 0 :(得分:67)

此实现没有内存占用。

/**
 * @param begin inclusive
 * @param end exclusive
 * @return list of integers from begin to end
 */
public static List<Integer> range(final int begin, final int end) {
    return new AbstractList<Integer>() {
            @Override
            public Integer get(int index) {
                return begin + index;
            }

            @Override
            public int size() {
                return end - begin;
            }
        };
}

编辑:

在Java 8中,您可以简单地说:

IntStream.range(begin, end).iterator()                // returns PrimitiveIterator.OfInt

或者如果您需要盒装版本:

IntStream.range(begin, end).boxed().iterator()        // returns Iterator<Integer>

答案 1 :(得分:15)

未测试。将其映射到“min,count”是留给读者的练习。

public class IntRangeIterator implements Iterator<Integer> {
  private int nextValue;
  private final int max;
  public IntRangeIterator(int min, int max) {
    if (min > max) {
      throw new IllegalArgumentException("min must be <= max");
    }
    this.nextValue = min;
    this.max = max;
  }

  public boolean hasNext() {
    return nextValue <= max;
  }

  public Integer next() {
    if (!hasNext()) {
      throw new NoSuchElementException();
    }
    return Integer.valueOf(nextValue++);
  }

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

答案 2 :(得分:9)

如果你真的想要最短的代码量,那么Bombe的回答很好。然而,它没有充分理由吸引记忆。如果你想自己实现它,它将是:

import java.util.*;

public class IntegerRange implements Iterator<Integer>
{
    private final int start;
    private final int count;

    private int position = -1;

    public IntegerRange(int start, int count)
    {
        this.start = start;
        this.count = count;
    }

    public boolean hasNext()
    {
        return position+1 < count;
    }

    public Integer next()
    {
        if (position+1 >= count)
        {
            throw new NoSuchElementException();
        }
        position++;
        return start + position;
    }

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

答案 3 :(得分:7)

使用番石榴框架的一个例子。请注意,这不会实现集合(尽管您必须阅读ContiguousSet实现以验证它)。

import com.google.common.collect.ContiguousSet;
import com.google.common.collect.DiscreteDomain;
import com.google.common.collect.DiscreteDomains;

class RangeIterator { 

    public Iterator<Integer> range(int start, int length) {
        assert length > 0;
        Range<Integer> dim_range = Ranges.closedOpen(start, start + length);
        DiscreteDomain<Integer> ints = DiscreteDomains.integers();
        ContiguousSet<Integer> dim = dim_range.asSet(ints);
        return dim.iterator();
    }
}

答案 4 :(得分:4)

直接执行你的作业:

List<Integer> ints = new ArrayList<Integer>();
for (int i = 0; i < count; i++) {
    ints.add(first + i);
}

答案 5 :(得分:4)

在java 8中使用流API的示例:

int first = 0;
int count = 10;
Iterator<Integer> it = IntStream.range(first, first + count).iterator();
while (it.hasNext()) {
    System.out.println(it.next());
}

没有迭代器,可能是:

int first = 0;
int count = 10;
IntStream.range(first, first + count).forEach(i -> System.out.println(i));

答案 6 :(得分:2)

通常认为传递Collection和朋友而不是Iterator的好风格(请参阅this FAQ entry),所以我建议使用类似

的内容
public final class IntegerRange implements Set<Integer> {
        final LinkedHashSet<Integer> backingList;
        public IntegerRange(final int start, final int count) {
                backingList = new LinkedHashSet(count, 1.0f);
                for (int i=0; i < count; i++) {
                        backingList.set(i, start + i);
                }       
        }       
        /** Insert a bunch of delegation methods here */
}

然后在需要将.iterator()传递给您正在使用的任何框架时使用Iterator

更新:显然,这段代码不是懒惰的。如果您无法负担存储(可能)2 ^ 32-1 Integer s的额外内存开销,则应使用其他解决方案。此外,没有关于类型的保证范围将被排序(即使它是基于实现)。如果您需要保证排序,可以考虑实施SortedSet并使用TreeSet进行备份,但构建范围需要更长时间。老实说,如果你关注的是正确的细节,那么寻找图书馆可能是值得的。例如,Tapestry有一个internal version