Как поменять элементы на 2D массиве функциональным способом в JAVA - PullRequest
0 голосов
/ 26 октября 2019

Я пытаюсь реорганизовать императивную функцию транспонирования в декларативную. Вот императивная реализация:

for (int i = 0; i < routes.length; i++) {
        for (int j = i; j < routes.length; j++) {
            Route temp = routes[j][i];
            routes[j][i] = routes[i][j];
            routes[i][j] = temp;
        }
    }

А вот моя отчаянная попытка, которая застряла из-за когнитивной нагрузки:

Arrays.stream(routes).forEach(routes1 -> Arrays.stream(routes1).forEach(
            route -> {
                Route temp ??
            }
    ));

Я полагаю, что решение заключается в использовании карты вместо forEach, но яЯ не уверен.

1 Ответ

0 голосов
/ 26 октября 2019

Вы можете сделать что-то вроде этого:

int[][] routes = {{1, 2, 3},
                  {4, 5, 6},
                  {7, 8, 9}};

// convert columns to rows
Map<Integer, List<AbstractMap.SimpleEntry<Integer, Integer>>> rows = Arrays.stream(routes)
        .flatMap(ints -> IntStream.range(0, ints.length).mapToObj(i -> new AbstractMap.SimpleEntry<>(i, ints[i])))
        .collect(Collectors.groupingBy(AbstractMap.SimpleEntry::getKey));

// extract values from rows
Integer[][] result = rows.values().stream().map(simpleEntries -> simpleEntries.stream()
        .map(AbstractMap.SimpleEntry::getValue).toArray(Integer[]::new))
        .toArray(Integer[][]::new);

Вывод

1 4 7 
2 5 8 
3 6 9 

Можно подумать о транспонировании матрицы как преобразовании столбцов в строки, то естьосновная идея здесь. На первой карте мы группируем значения по индексу столбца, это будут новые строки, вторая часть просто извлекает значения из Map.

...