Есть ли что-то вроде C#/.NET
IEnumerable<int> range = Enumerable.Range(0, 100); //.NET
на Яве?
Есть ли что-то вроде C#/.NET
IEnumerable<int> range = Enumerable.Range(0, 100); //.NET
на Яве?
Отредактировано: как Java 8, это возможно с java.util.stream.IntStream.range(int startInclusive, int endExclusive)
В Java такого нет, но у вас может быть что-то вроде этого:
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();
}
};
}
}
Например, вы можете использовать Range следующим образом:
public class TestRange {
public static void main(String[] args) {
for (int i : new Range(1, 10)) {
System.out.println(i);
}
}
}
Также, если вам не нравится использовать new Range(1, 10)
напрямую, вы можете использовать для него фабричный класс:
public final class RangeFactory {
public static Iterable<Integer> range(int a, int b) {
return new Range(a, b);
}
}
А вот и наш заводской тест:
public class TestRangeFactory {
public static void main(String[] args) {
for (int i : RangeFactory.range(1, 10)) {
System.out.println(i);
}
}
}
Я надеюсь, что они будут полезны :)
next()
заключается в том, чтобы выдать NoSuchElementException
в случае, если метод вызывается, когда в итераторе больше нет элементов, поэтому я предлагаю добавить if (!hasNext()) throw new NoSuchElementException()
в качестве первого действия для next()
. :)
- person Ibrahim Arief; 09.09.2014
В Java нет встроенной поддержки для этого, однако ее очень легко создать самостоятельно. По большому счету API-интерфейсы Java предоставляют все, что вам нужно для такого рода функций, но не объединяют их в готовом виде.
Java использует подход, согласно которому существует бесконечное количество способов комбинировать вещи, так зачем отдавать предпочтение нескольким комбинациям над другими. При правильном наборе строительных блоков все остальное можно легко построить (это тоже философия Unix).
Другие языковые API (например, C# и Python) имеют более взвешенный взгляд, они выбирают несколько вещей, чтобы сделать их действительно простыми, но все же допускают более эзотерические комбинации.
Типичный пример проблемы с подходом Java можно увидеть в Java IO библиотека. Канонический способ создания текстового файла для вывода:
BufferedWriter out = new BufferedWriter(new FileWriter("out.txt"));
Библиотека Java IO использует шаблон декоратора, который действительно хорошая идея для гибкости, но наверняка чаще всего вам нужен буферизованный файл? Сравните это с эквивалентом в Python, который делает типичный вариант использования действительно простым:
out = file("out.txt","w")
Вы можете создать подкласс Arraylist для достижения того же:
public class Enumerable extends ArrayList<Integer> {
public Enumerable(int min, int max) {
for (int i=min; i<=max; i++) {
add(i);
}
}
}
Затем используйте итератор, чтобы получить последовательность целых чисел от минимального до максимального (включая оба)
ИЗМЕНИТЬ
Как уже упоминал sepp2k, приведенное выше решение быстрое, грязное и практичное, но имеет некоторые серьезные недостатки (не только O (n) в пространстве, хотя оно должно иметь O (1)). Для более серьезной эмуляции класса C# я бы предпочел написать собственный класс Enumerable, который реализует Iterable и собственный итератор (но не здесь и сейчас;)).
GetEnumerator
или используете его в foreach
, IEnumerable
заполняется фактическими значениями. Документы MSDN: msdn.microsoft.com/en-us /библиотека/
- person Powerlord; 01.06.2010
foreach(int i in Enumerable.Range(0, 1000000000)) {/*...*/}
без видимого увеличения потребления памяти, поэтому я убежден, что он не хранит в памяти все значения от 0 до 1000000000.
- person sepp2k; 01.06.2010