Shortest way to get an Iterator over a range of Integers in Java

后端 未结 7 1944
时光说笑
时光说笑 2020-12-29 22:27

What\'s the shortest way to get an Iterator over a range of Integers in Java? In other words, implement the following:

/** 
* Returns an Iterator over the in         


        
相关标签:
7条回答
  • 2020-12-29 22:35

    Untested. Mapping that onto "min, count" is left as an exercise for the reader.

    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();
      }
    }
    
    0 讨论(0)
  • 2020-12-29 22:36

    If you actually want the shortest amount of code, then Bombe's answer is fine. However, it sucks memory for no good reason. If you want to implement it yourself, it would be something like:

    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();
        }
    }
    
    0 讨论(0)
  • 2020-12-29 22:47

    Straight-forward implementation of your homework:

    List<Integer> ints = new ArrayList<Integer>();
    for (int i = 0; i < count; i++) {
        ints.add(first + i);
    }
    
    0 讨论(0)
  • 2020-12-29 22:48

    This implementation does not have a memory footprint.

    /**
     * @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;
                }
            };
    }
    

    Edit:

    In Java 8 you can simply say:

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

    or if you need the boxed version:

    IntStream.range(begin, end).boxed().iterator()        // returns Iterator<Integer>
    
    0 讨论(0)
  • 2020-12-29 22:56

    An example using the guava framework. Note that this will not materialize the set (although you have to read the ContiguousSet implementation to verify that).

    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();
        }
    }
    
    0 讨论(0)
  • 2020-12-29 22:57

    A sample using stream API in java 8:

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

    Without iterator, it could be:

    int first = 0;
    int count = 10;
    IntStream.range(first, first + count).forEach(i -> System.out.println(i));
    
    0 讨论(0)
提交回复
热议问题