Можно ли заменить Integer [] на int []? - PullRequest
1 голос
/ 31 мая 2019

Я пытаюсь немного переписать свой код.Возможно ли использовать массив int[] вместо Integer[] в моем коде?

Когда я заменяю все Integer[] на int[], я застрял в части замены:

.toArray(Integer[]::new);

с

.toArray(int[]::new);
public class Main {

    private static final int MODULO = (int) (Math.pow(10, 9) + 7);

    private static int modulate(final long result) {
        return (int) (result % MODULO);
    }

    //private static

    private static Integer[] steps(final int smaller, final int larger) {
        final int lcm = lowestCommonMultiple(smaller, larger);
        final int max = lcm / smaller;
        final int min = lcm / larger;
        final Integer[] result = new Integer[max * 2];

        int pos = 0;
        for (int i = 1; i <= max; i++) {
            result[pos++] = (i * smaller);
            if (i <= min) {
                result[pos++] = (i * larger);
            }
        }
        return Arrays.stream(result)
                .filter(Objects::nonNull)
                .sorted()
                .distinct()
                .toArray(Integer[]::new);
    }

    private static long nthNonZeroMagicalNumber(final int N, final int smaller, final int larger) {
        final Integer[] stepsInCycle = steps(smaller, larger);
        final long lcm = stepsInCycle[stepsInCycle.length - 1];
        final int inOneCycle = stepsInCycle.length;
        final int fullCycleCount = N / inOneCycle;
        int count = fullCycleCount * inOneCycle;
        final long evaluated = fullCycleCount * lcm;
        if (count == N) {
            return evaluated;
        }
        final int remainder = N - count - 1;
        return stepsInCycle[remainder] + evaluated;
    }

    private static int greatestCommonDenominator(int a, int b) {
        while (b > 0) {
            int temp = b;
            b = a % b;
            a = temp;
        }
        return a;
    }

    public static int lowestCommonMultiple(final int a, final int b) {
        return a * (b / greatestCommonDenominator(a, b));
    }

    public static int nthMagicalNumber(final int N, final int A, final int B) {
        if (N == 0) {
            return 0;
        } else if (A == B) {
            final long result = (long) A * (long) N;
            return modulate(result);
        } else if (N == 1) {
            return modulate(Math.min(A, B));
        }
        return modulate(nthNonZeroMagicalNumber(N, Math.min(A, B), Math.max(A, B)));
    }

    public static void main(String[] args) {
        int result = nthMagicalNumber(53776, 22434, 31343);

    }
}

Если кто-то может дать мне какой-либо совет, я буду очень признателен.Заранее спасибо!

1 Ответ

3 голосов
/ 31 мая 2019

Предполагая, что вы начинаете с Integer[], вы можете распаковать целые числа в потоке, что даст IntStream от вашего Stream<Integer>.

// if result is an Integer[]
return Arrays.stream(result)
        .filter(Objects::nonNull)
        .sorted()
        .distinct()
        .mapToInt(n -> n) // this gives an IntStream
        .toArray();       // this returns an int[]

Если вы на самом деле измените массив result на тип int[], тогда вам не понадобится распаковка, но вы больше не сможете отфильтровывать элементы, используя nonNull: неписанные элементы в вашем массиве будет ноль вместо нуля. Таким образом, вы должны иметь:

// if result is an int[]
return Arrays.stream(result)
             .filter(n -> n!=0)
             .sorted()
             .distinct()
             .toArray();

Возможно, вам лучше использовать списки, а не массивы. При необходимости список может увеличиваться в размере, поэтому вам не нужно отслеживать, какую позицию вы достигли, или исключать элементы, в которые вы не записали.

...