Заполнить массивы диапазонами чисел - PullRequest
25 голосов
/ 02 августа 2010

Существует ли какой-либо синтаксис / пакет, позволяющий быстро заполнять массивы 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

Это не так уж сложно реализовать, но ядумаю, это может быть распространенным явлением, поэтому, возможно, это уже было сделано.

Ответы [ 6 ]

85 голосов
/ 04 мая 2015

Для тех, кто все еще ищет решение:

В Java 8 или новее на это можно ответить тривиально, используя Streams без каких-либо циклов или дополнительных библиотек.

int[] range = IntStream.rangeClosed(1, 10).toArray();

Будет создан массив с целыми числами от 1 до 10.

Более общее решение, которое дает тот же результат, приведено ниже. Это можно сделать для получения любой последовательности, изменив унарный оператор.

int[] range = IntStream.iterate(1, n -> n + 1).limit(10).toArray();
17 голосов
/ 02 августа 2010

Есть доллар :

// 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>
8 голосов
/ 01 июня 2014

Что касается первого вопроса, возможно ли заполнить массив значениями диапазона: на самом деле этого можно достичь с помощью комбинации Range , DiscreteDomain, ContiguousSet и Ints из Гуава :

int[] array = Ints.toArray(
    ContiguousSet.create(Range.closed(1, 500), DiscreteDomain.integers()));

И, не совсем то, что упоминается во второй части вопроса, но можно создать набор с элементами диапазона дискретной области:

Set<Integer> numbersFrom1To500 = 
    ContiguousSet.create(Range.closed(1, 500), DiscreteDomain.integers());

Полученный Set не будет содержать указанные элементы физически, только логически (поэтому его объем памяти будет небольшим), но может быть повторен (поскольку это Set):

for (Integer integer : numbersFrom1To500) {
    System.out.println(integer);
}
8 голосов
/ 02 августа 2010

Не так чисто, как в ответе Soft 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;
    }

}

Обратите внимание, вам нужно несколько статических импортов, чтобы это работало.

5 голосов
/ 27 апреля 2017

Другое полезное и малоизвестное решение Java 8 для существующих массивов:

int[] array = new int[10];
Arrays.setAll(array, i -> i + 1);
1 голос
/ 31 мая 2016
    List<Integer> arrayOfRange  = new ArrayList<Integer>();
    int[] range = IntStream.iterate(1, n -> {arrayOfRange.add(n);return n + 1;}).limit(10).toArray();

// В дополнение к тому, что Craig ответит, если вы хотите, чтобы Integer 2nd подход

List<Integer> list = IntStream.of(range).boxed().collect(Collectors.toList());
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...