Есть ли простой и приятный способ сгенерировать List<Integer>
, или, возможно, Integer[]
или int[]
с последовательными значениями от некоторого start
значения к end
значению?
То есть что-то короче, но эквивалентно 1 следующему:
void List<Integer> makeSequence(int begin, int end) {
List<Integer> ret = new ArrayList<>(end - begin + 1);
for (int i=begin; i<=end; i++) {
ret.add(i);
}
return ret;
}
Использование гуавы - это нормально.
Обновить:
Анализ производительности
Поскольку на этот вопрос было получено несколько хороших ответов, как с использованием собственной Java 8, так и сторонних библиотек, я подумал, что протестирую производительность всех решений.
Первый тест просто тестирует создание списка из 10 элементов [1..10]
с использованием следующих методов:
- classicArrayList : код, приведенный выше в моем вопросе (и, по сути, такой же, как ответ adarshr).
- eclipseCollections : код, указанный в ответе Дональда ниже с использованием Eclipse Collections 8.0.
- guavaRange : код, указанный в ответе daveb ниже. Технически это создает не a,
List<Integer>
а скорееContiguousSet<Integer>
- но, поскольку он реализуетсяIterable<Integer>
по порядку, он в основном работает для моих целей. - intStreamRange : код, приведенный в ответе Владимира ниже, который использует
IntStream.rangeClosed()
- который был введен в Java 8. - streamIterate : код, приведенный в ответе Каталина ниже, который также использует
IntStream
функции, представленные в Java 8.
Вот результаты в килограммах операций в секунду (чем больше, тем лучше), для всего вышеперечисленного со списками размером 10:
... и снова для списков размером 10 000:
Последняя диаграмма верна - решения, отличные от Eclipse и Guava, слишком медленные, чтобы получить даже полосу в один пиксель! Быстрые решения в 10–20 000 раз быстрее остальных.
Конечно, здесь происходит то, что решения guava и eclipse на самом деле не материализуют какой-либо список из 10 000 элементов - они просто фиксированные обертки вокруг начальной и конечной точек. Каждый элемент создается по мере необходимости во время итерации. Поскольку мы на самом деле не повторяем этот тест, затраты откладываются. Все остальные решения фактически материализуют полный список в памяти и платят высокую цену в тесте, предназначенном только для создания.
Давайте сделаем что-нибудь более реалистичное, а также переберем все целые числа, суммируя их. Итак, в случае IntStream.rangeClosed
варианта тест выглядит так:
@Benchmark
public int intStreamRange() {
List<Integer> ret = IntStream.rangeClosed(begin, end).boxed().collect(Collectors.toList());
int total = 0;
for (int i : ret) {
total += i;
}
return total;
}
Здесь картинки сильно меняются, хотя нематериализационные решения по-прежнему самые быстрые. Здесь длина = 10:
... и длина = 10,000:
Долгая итерация по многим элементам во многом уравновешивает ситуацию, но затмение и гуава остаются более чем в два раза быстрее даже при тесте на 10 000 элементов.
Так что, если вы действительно хотите List<Integer>
, коллекции eclipse кажутся лучшим выбором, но, конечно, если вы используете потоки более естественным способом (например, забывая .boxed()
и сокращая примитивный домен), вы, вероятно, закончите быстрее, чем все эти варианты.
1 Возможно, за исключением обработки ошибок, например, если end
< begin
, или если размер превышает некоторые ограничения реализации или JVM (например, массивы больше, чем 2^31-1
.
источник
Ответы:
С Java 8 это настолько просто, что ему больше не нужен отдельный метод:
источник
Что ж, этот лайнер может соответствовать требованиям (использует диапазоны Guava )
Это не создает
List<Integer>
, ноContiguousSet
предлагает почти те же функции, в частности реализацию,Iterable<Integer>
которая позволяетforeach
реализовать таким же образом, какList<Integer>
.В более старых версиях (где-то до Guava 14) вы могли использовать это:
Оба производят:
источник
asList()
его, если вам действительно не нуженList
...,ContiguousSet
созданный с помощьюasSet
легковесного (ему просто нужен диапазон и домен), ноasList()
создаст список, который фактически хранит все элементы в памяти (в настоящее время).Range
существует, но нет,Ranges
и они покончили с этимasSet
методом. В моей более старой версииasSet
он устарел и, похоже, они удалили его. Диапазоны, по-видимому, должны использоваться только для смежных коллекций, и они принудительно применяют это, хотя мне нравится это решение.Следующая однострочная версия Java 8 сгенерирует [1, 2, 3 ... 10]. Первый аргумент
iterate
- это первый номер в последовательности, а первый аргументlimit
- это последнее число.источник
Вы можете использовать
Interval
класс из Eclipse Collections .Interval
Класс ленив, поэтому не сохраняет все значения.Ваш метод можно будет реализовать следующим образом:
Если вы не хотите помещать целые числа как целые числа, но все же хотите получить в результате структуру списка, вы можете использовать
IntList
withIntInterval
from Eclipse Collections.IntList
есть методыsum()
,min()
,minIfEmpty()
,max()
,maxIfEmpty()
,average()
иmedian()
доступны на интерфейсе.Обновление для ясности: 27.11.2017
An
Interval
- этоList<Integer>
, но он ленивый и неизменный. Это чрезвычайно полезно для генерации тестовых данных, особенно если вы много работаете с коллекциями. Если вы хотите , вы можете легко скопировать интервал кList
,Set
илиBag
следующим образом :IntInterval
ЭтоImmutableIntList
который простираетсяIntList
. Также есть конвертерные методы.У An
Interval
и anIntInterval
разныеequals
контракты.Обновление для коллекций Eclipse 9.0
Теперь вы можете создавать примитивные коллекции из примитивных потоков. Существуют
withAll
иofAll
методы в зависимости от ваших предпочтений. Если вам интересно, я объясню, почему у нас здесь оба . Эти методы существуют для изменяемых и неизменяемых Int / Long / Double Lists, Sets, Bags и Stacks.Примечание: я являюсь участником коллекций Eclipse.
источник
Это самое короткое, что я мог получить с помощью Core Java.
источник
for(int i = begin; i <= end; ret.add(i++));
:)ret.add(i)
части в приращение цикла for сделает это «короче». Полагаю, по этой логике, если бы я написал все в одну строчку, было бы короче :)Вы можете использовать диапазоны гуавы
Вы можете получить
SortedSet
, используяисточник
Это самое короткое, что я смог найти.
Версия списка
Версия массива
источник
Это может сработать для вас ....
источник