Pergunta

Is there something like C#/.NET's

IEnumerable<int> range = Enumerable.Range(0, 100); //.NET

in Java?

Foi útil?

Solução

Edited: As Java 8, this is possible with java.util.stream.IntStream.range(int startInclusive, int endExclusive)

Before Java8:

There is not such thing in Java but you can have something like this:

import java.util.Iterator;

public class Range implements Iterable<Integer> {
    private int min;
    private int count;

    public Range(int min, int count) {
        this.min = min;
        this.count = count;
    }

    public Iterator<Integer> iterator() {
        return new Iterator<Integer>() {
            private int cur = min;
            private int count = Range.this.count;
            public boolean hasNext() {
                return count != 0;
            }

            public Integer next() {
                count--;
                return cur++; // first return the cur, then increase it.
            }

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

For example you can use Range by this way:

public class TestRange {

    public static void main(String[] args) {
        for (int i : new Range(1, 10)) {
            System.out.println(i);
        }
    }

}

Also if you don't like use new Range(1, 10) directly, you can use factory class for it:

public final class RangeFactory {
    public static Iterable<Integer> range(int a, int b) {
        return new Range(a, b);
    }
}

And here is our factory test:

public class TestRangeFactory {

    public static void main(String[] args) {
        for (int i : RangeFactory.range(1, 10)) {
            System.out.println(i);
        }
    }

}

I hope these will be useful :)

Outras dicas

There is no built in support for this in Java, however it is very easy to build it yourself. By and large the Java APIs provide all the bits you need for this kind of functionality but do not combine them out of the box.

Java takes the approach that there is an infinite number of ways to combine things so why privilege a few combinations over others. With the right set of building blocks everything else can be easily built (this is also the Unix philosophy).

Other language API's (C# and Python for example) take a more measured view, they do pick a few things to make really easy, but still allow more esoteric combinations.

A typical example of the problem with the Java approach can be seen in the Java IO library. The canonical way to create a text file for output is:

BufferedWriter out = new BufferedWriter(new FileWriter("out.txt"));

The Java IO library uses the Decorator Pattern which is a really good idea for flexibility, but surely more often than not you need a buffered file? Compare that to the equivalent in Python, which makes the typical use case really simple:

out = file("out.txt","w")

You could subclass an Arraylist to achieve the same:

public class Enumerable extends ArrayList<Integer> {   
   public Enumerable(int min, int max) {
     for (int i=min; i<=max; i++) {
       add(i);
     }
   }    
}

Then use the iterator to get a sequence of Integers from min to max (both including)

EDIT

As sepp2k mentioned - the solution above is quick, dirty and practical but has some serious withdraws (not only O(n) in space while it should have O(1)). For a more serious emulation of the C# class I'd rather write a custom Enumerable class that implements Iterable and a custom iterator (but not here and now ;) ).

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top