Python как диапазон с степпингом в чистой Java - PullRequest
1 голос
/ 22 сентября 2019
In [1]: range(-100, 100, 20)
Out[1]: [-100, -80, -60, -40, -20, 0, 20, 40, 60, 80]

Какой самый простой способ создать Array, как описано выше, с использованием стандартных библиотек Java вместо написания собственной функции?

Существует IntStream.range(-100, 100), но шаг жестко задан в 1.


ЭТО НЕ ДУБЛИКАТ Java: эквивалент диапазона Python (int, int)? , потому что мне нужно step (смещение) между числами и я хочу использоватьв библиотеках вместо сторонних библиотек.Я проверил этот вопрос и ответы, прежде чем добавить свой.Разница тонкая, но существенная.

Ответы [ 4 ]

7 голосов
/ 22 сентября 2019

Использование IntStream::range должно работать (для вашего специального шага 20).

IntStream.range(-100, 100).filter(i -> i % 20 == 0);

Общая реализация, допускающая отрицательные шаги, может выглядеть следующим образом:

/**
 * Generate a range of {@code Integer}s as a {@code Stream<Integer>} including
 * the left border and excluding the right border.
 * 
 * @param fromInclusive left border, included
 * @param toExclusive   right border, excluded
 * @param step          the step, can be negative
 * @return the range
 */
public static Stream<Integer> rangeStream(int fromInclusive,
        int toExclusive, int step) {
    // If the step is negative, we generate the stream by reverting all operations.
    // For this we use the sign of the step.
    int sign = step < 0 ? -1 : 1;
    return IntStream.range(sign * fromInclusive, sign * toExclusive)
            .filter(i -> (i - sign * fromInclusive) % (sign * step) == 0)
            .map(i -> sign * i)
            .boxed();
}

Подробнее см. https://gist.github.com/lutzhorn/9338f3c43b249a618285ccb2028cc4b5.

5 голосов
/ 22 сентября 2019

То же самое может быть достигнуто с помощью IntStream::iterate (доступно с JDK9), которое принимает семена, IntPredicate и IntUnaryOperator.С использованием вспомогательного метода это выглядело бы так:

public static int[] getInRange(int min, int max, int step) {
        return IntStream.iterate(min, operand -> operand < max, operand -> operand + step)
                .toArray();
}
2 голосов
/ 23 сентября 2019

Другой способ:

List<Integer> collect = Stream.iterate(-100, v -> v + 20).takeWhile(v -> v < 100)
    .collect(Collectors.toList());

Аналогичная версия с IntStream:

List<Integer> collect = IntStream.iterate( -100, v -> v + 20).takeWhile(v -> v < 100)
    .boxed().collect(Collectors.toList());

Но на основе этот ответ вышеуказанные коды можно изменить на (с помощью IntStream или Stream)

List<Integer> collect = Stream.iterate(-100, v -> v < 100, v -> v + 20)
    .collect(Collectors.toList());
0 голосов
/ 23 сентября 2019

Может быть лучше итерировать только необходимые последовательности.

IntStream.range(-100 / 20, 100 / 20).map(i -> i * 20); // only iterate [-5, 5] items
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...