Заполнение массивов диапазонами чисел
Есть ли синтаксис/пакет, позволяющий быстро заполнять массивы java с диапазонами чисел, например, в perl?
например.
int[] arr = new int[1000];
arr=(1..500,301..400,1001..1400); // returns [1,2,3,4,...,500,301,302,...,400,1001,1002,...1400]
Кроме того, он представляет собой пакет, который позволяет получить n-й номер в таком списке чисел, как указано выше, без фактического создания массива (который может быть огромным)?
например.
BunchOfRangesType bort = new BunchOfRangesType("1..500","301..400","1001..1400");
bort.get(0); // return 1
bort.get(500); // return 301
bort.get(501); // return 302
Это не слишком сложно реализовать, но я предполагаю, что это может быть распространено, поэтому, возможно, это уже было сделано.
Ответы
Ответ 1
Не так чисто, как True Soft ответ, но вы можете использовать Google Guava для того же эффекта:
public class Test {
public static void main(String[] args) {
//one liner
int[] array = toArray(newLinkedList(concat(range(1, 10), range(500, 1000))));
//more readable
Iterable<Integer> values = concat(range(1, 10), range(500, 1000));
List<Integer> list = newLinkedList(values);
int[] array = toArray(list);
}
public static List<Integer> range(int min, int max) {
List<Integer> list = newLinkedList();
for (int i = min; i <= max; i++) {
list.add(i);
}
return list;
}
}
Обратите внимание, что для этого вам потребуется несколько статических импортеров.
Ответ 2
Для тех, кто все еще ищет решение:
В Java 8 или более поздней версии это можно получить тривиально с помощью Streams без каких-либо циклов или дополнительных библиотек.
int[] range = IntStream.rangeClosed(1, 10).toArray();
Это приведет к созданию массива с целыми числами от 1 до 10.
Более общее решение, которое дает тот же результат, приведено ниже. Это можно сделать, чтобы произвести любую последовательность, модифицируя унарный оператор.
int[] range = IntStream.iterate(1, n -> n + 1).limit(10).toArray();
Ответ 3
Существует dollar:
// build the List 10, 11, 12, 13, 14
List<Integer> list2 = $(10, 15).toList();
Maven:
<dependency>
<groupId>org.bitbucket.dollar</groupId>
<artifactId>dollar</artifactId>
<version>1.0-beta3</version>
</dependency>
Ответ 4
Что касается первого вопроса, можно ли заполнить массив значениями диапазона: на самом деле можно добиться этого с помощью комбинации Range, DiscreteDomain, ContiguousSet и Ints из Guava:
int[] array = Ints.toArray(
ContiguousSet.create(Range.closed(1, 500), DiscreteDomain.integers()));
И не совсем то, что упоминается во второй части вопроса, но можно создать набор с элементами диапазона дискретного домена:
Set<Integer> numbersFrom1To500 =
ContiguousSet.create(Range.closed(1, 500), DiscreteDomain.integers());
Результирующий Set
не будет содержать указанные элементы физически, только логически (поэтому объем памяти будет мал), но может быть повторен (так как это a Set
):
for (Integer integer : numbersFrom1To500) {
System.out.println(integer);
}
Ответ 5
Другое полезное и не широко известное решение Java 8 для существующих массивов:
int[] array = new int[10];
Arrays.setAll(array, i -> i + 1);
Ответ 6
List<Integer> arrayOfRange = new ArrayList<Integer>();
int[] range = IntStream.iterate(1, n -> {arrayOfRange.add(n);return n + 1;}).limit(10).toArray();
//в дополнение к тому, что ответ Craig, если вы хотите иметь Integer
2-й вопрос
List<Integer> list = IntStream.of(range).boxed().collect(Collectors.toList());