Декартово произведение двух массивов int с использованием потоков Java 8 - PullRequest
0 голосов
/ 29 июня 2018

У меня есть два массива типа int, a = {10,20,30} и {1,2,3}.

Я бы хотел получить декартово произведение из этих двух массивов.

Когда я использую List из Integer с, логика работает нормально:

    List<Integer> intList = Arrays.asList(10,20,30);
    List<Integer> intList1 = Arrays.asList(1,2,3);
    intList.stream().flatMap(i -> intList1.stream().map(j -> new int[]{i,j})).collect(Collectors.toList());

Однако, когда я использую int[], я получаю ошибку компиляции.

Ошибка: (16, 79) Java: несовместимые типы: неверный тип возврата в лямбда-выражении выражение не существует экземпляра (ов) переменной типа (ов) U, так что java.util.stream.Stream соответствует java.util.stream.IntStream

    int[] intArray = {10,20,30};
    int[] intArray1 = {1,2,3};
    Arrays.stream(intArray).flatMap(i -> Arrays.stream(intArray1).mapToObj(j -> new int[]{j,i})).collect(Collectors.toList());

Пожалуйста, помогите мне понять, что здесь не так.

P. S.

Arrays.stream(intArray).mapToObj(i -> new int[]{i,i+1}).collect(Collectors.toList());

Производит вывод как {(10,11),(20,21),(30,31)}.

1 Ответ

0 голосов
/ 29 июня 2018

Во втором случае Arrays.stream(intArray) возвращает IntStream.
Так что flatMap() ожидает в качестве параметра поток, совместимый с:

Arrays.stream(intArray)
      .flatMap(i -> Arrays.stream(intArray1)
                     .mapToObj(j -> new int[] { j, i }))

Но лямбда flatMap() производит Stream<int[]>, и вы не можете отобразить IntStream в Stream неявно.
Принимая во внимание, что ошибка компиляции.
Итак, сначала сопоставьте ваш IntStream с Stream<Integer>:

List<int[]> collect = 
Arrays.stream(intArray)
      .boxed()
      .flatMap(i -> Arrays.stream(intArray1)
                          .mapToObj(j -> new int[] { j, i }))
      .collect(Collectors.toList());

Это менее эффективно, чем ваше первоначальное намерение (из-за целочисленного бокса), но оно будет работать.
Обратите внимание, что, как правило, вы должны избегать создания List массива. Они не предназначены для совместной работы.
это верно в целом и для потоков тоже.

Редактировать

Решение Holger, предоставленное в качестве комментария, предотвращает бокс:

List<int[]> collect = Arrays.stream(intArray)
                                  .mapToObj(i -> Arrays.stream(intArray1)
                                                       .mapToObj(j -> new int[] { j, i }))
                                  .flatMap(Function.identity())
                                  .collect(Collectors.toList());

Сначала он сопоставляет IntStream с Stream<Stream<int[]>>, а затем вызывается flatMap(), чтобы объединить его в <Stream<int[]>.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...