54

I'd like to have a list which contains the integers in the range 1 to 500. Is there some way to create this list using Guava (or just plain Java) without having to loop through the range and add the values individually within my own code?

Ivar
  • 6,138
  • 12
  • 49
  • 61

4 Answers4

136

The new, Java 8 way:

List<Integer> range = IntStream.range(1, 501).boxed().collect(Collectors.toList());
Leponzo
  • 624
  • 1
  • 8
  • 20
Norswap
  • 11,740
  • 12
  • 47
  • 60
  • 2
    This is pretty cool; however, do you not receive a cast warning/compiler error? – Thomas Apr 26 '15 at 18:07
  • 1
    No, do you? If so it might be because you did not enable support for Java 8 language features (or older -- here I'm thinking type inference) in your IDE (it's possible to have a Java 8 JDK, have access to all the libraries and not have the language features support). – Norswap Apr 29 '15 at 00:09
  • 3
    With Java 16 you can make it even shorter: `IntStream.range(1, 501).boxed().toList()` – Franziskus Karsunke Feb 17 '23 at 17:15
15

Using Guava, you can resort to a Range: https://guava.dev/releases/19.0/api/docs/com/google/common/collect/Range.html

Of course, there will still be loops in your code, but they just might be hidden from the code for simplicity sake.

For instance:

Range<Integer> yourValues = Range.closed(1, 500);

Check https://github.com/google/guava/wiki/RangesExplained for some more examples.

Keep in mind that if you do need to eventually iterate over the Range, you cannot do so directly, only through using DiscreteDomains.integers().

Leponzo
  • 624
  • 1
  • 8
  • 20
pcalcao
  • 15,789
  • 1
  • 44
  • 64
  • 2
    Thanks this pointed me in the right direction. The final code I needed was ImmutableList.copyOf(ContiguousSet.create(Range.closed(1, 500), DiscreteDomain.integers())) –  May 23 '13 at 10:28
  • 2
    @jgm You don't have to do the `ImmutableList` copy because `ContiguousSet` is already an immutable collection (`ImmutableSortedSet`) which has `asLst()` method returning `ImmutableList` view. – Grzegorz Rożniecki May 23 '13 at 10:38
  • BTW Creating `ImmutableList` from `ContiguousSet` which has unbounded range like `Range.atLeast(1)` can result in OutOfMemoryError. – Grzegorz Rożniecki May 23 '13 at 10:46
1

Btw. if it is only to be used in some sort of iteration, you could simply create a basic class which implements the Iterable interface, to skip the insertion altogether.

Something like this:

import java.util.Iterator;

public class IntegerRange implements Iterable<Integer> {
    private int start, end;

    public IntegerRange(int start, int end) {
        if (start <= end) {
            this.start = start;
            this.end = end;
        } else {
            this.start = end;
            this.end = start;
        }
    }

    @Override
    public Iterator<Integer> iterator() {
        return new IntegerRangeIterator();
    }

    private class IntegerRangeIterator implements Iterator<Integer> {
        private int current = start;

        @Override
        public boolean hasNext() {
            return current <= end;
        }

        @Override
        public Integer next() {
            return current++;
        }
    }
}

Which could be used in some way like this:

Iterable<Integer> range = new IntegerRange(1, 500);

for (int i : range) {
    // ... do something with the integer
}
Feirell
  • 719
  • 9
  • 26
1

You can also use Apache Commons IntRange utility

E.g.

    private List<Integer> getAllIntegerRange(Integer firstValue, Integer secondValue) {
    List<Integer> values = new ArrayList<>();
    IntRange rang = new IntRange(firstValue, secondValue);
    int[] ranges = rang.toArray();
    for (int i : ranges) {
        values.add(i);
    }
    return values;
}
nilesh virkar
  • 429
  • 2
  • 12