Сравните два целочисленных массива с помощью Java Stream

У меня есть два целочисленных массива, например. -

int[] a = {2, 7, 9}

int[] b = {4, 2, 8}

Я хочу сравнить его поэлементно, то есть 2 с 4, затем 7 с 2 и, наконец, 9 с 8. Каждый результат сравнения будет сохранен в списке.

Это довольно легко сделать традиционными способами Java. Но я хочу использовать здесь Stream. Есть указатели?

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
10
0
4 684
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Ответ принят как подходящий

Вы можете сделать это так,

List<Boolean> equalityResult = IntStream.range(0, a.length).mapToObj(i -> a[i] == b[i])
                .collect(Collectors.toList());

Предварительное условие: оба массива имеют одинаковый размер.

Предполагая, что длина обоих входных массивов одинакова

List<Integer> list = IntStream.range(0, a.length).mapToObj(i -> Integer.compare(a[i], b[i]))
            .collect(Collectors.toCollection(() -> new ArrayList<>(a.length)));

Вы можете использовать toList() вместо toCollection(...)

Peter Lawrey 14.10.2018 17:41

@PeterLawrey Спасибо за предложение, я тоже об этом подумал. Ждал, чтобы кто-нибудь просмотрел это и помог мне понять, может ли инициализация массива с емкостью, такой как в () -> new ArrayList<>(a.length), быть чем-то полезным, чем Supplier<List<T>>) ArrayList::new (возможно, емкость по умолчанию!) С этой реализацией сборщиков?

Naman 14.10.2018 18:28

По емкости пока нет хорошего решения. Инициализация ArrayList с количеством ожидаемых элементов может быть хорошей для последовательного потока, но приведет к возникновению слишком больших временных массивов с параллельным потоком. Сегодня лучшим решением будет List<Integer> list = Arrays.asList( /* your stream operation */ .toArray(Integer[]::new));, поскольку он будет использовать известное количество элементов даже в параллельном случае, позволяя всем потокам записывать в один последний массив, когда размеры предсказуемы, как в этом конкретном случае. Но не пытайтесь оптимизировать, если нет проблем с производительностью.

Holger 15.10.2018 10:03

То же, что и другие ответы, с небольшой разницей

List<Integer> result = IntStream.rangeClosed(0,a.length-1)
            .boxed()
            .map(i->Integer.compare(a[i],b[i]))
            .collect(Collectors.toList());

Вы можете использовать .mapToObj вместо .boxed().map

Peter Lawrey 14.10.2018 17:40

И вы можете использовать range(0, a.length) вместо rangeClosed(0, a.length-1)

Peter Lawrey 14.10.2018 17:41

По сути, вы ищете функциональность операции Zip (которая пока недоступна в Java).

Чтобы получить в результате набор логических значений, я бы рекомендовал:

boolean[] accumulator = new boolean[a.length];
IntStream.range(0, a.length)
         .forEachOrdered(i -> accumulator[i] = a[i] == b[i]);

и, соответственно, чтобы получить результат в виде int между соответствующими элементами в обоих массивах:

int[] ints = IntStream.range(0, a.length)
                      .map(i -> Integer.compare(a[i], b[i]))
                      .toArray();

Я не уверен, что forEachOrdered будет иметь значение в этом случае. c.f. для каждого

Peter Lawrey 14.10.2018 17:42

@PeterLawrey, я думаю, это вопрос предпочтений в данном конкретном случае. Так что да, вы правы, можно было просто использовать forEach.

Ousmane D. 14.10.2018 23:37

Другие вопросы по теме