Как преобразовать двумерный ArrayList<String> в массив с помощью stream API?

Рейтинг: -2Ответов: 1Опубликовано: 04.08.2023

Создание двумерного ArrayList:

ArrayList<String> map = new ArrayList<String>();
BufferedReader reader;
try {
    reader = new BufferedReader(new FileReader("map.txt"));
    String line = reader.readLine();
    while (line != null) {
        map.add(new String(line.strip()));
        line = reader.readLine();
    }
    reader.close();
} catch (IOException e) {
    e.printStackTrace();
}

Пробовал преобразовать в массив таким образом, как в статье на JavaRush:

String[][] zzz = map.toArray(new String[map.size()][map.get(0).length()]);

Ответы

▲ 0Принят

Во-первых, в вашем коде отсутствует двумерный список строк или список списков. Также не стоит давать название map переменной типа ArrayList во избежание путаницы, и при типизации этой переменной следовало бы исользовать интерфейс List, а не конкретную реализацию ArrayList.

Во-вторых, чтобы получить список строк из файла уже достаточно давно (со времён Java 8) существуют методы "нового" ввода/вывода типа Files.lines (по умолчанию используется кодировка UTF-8), т.е. можно реализовать отдельный метод:

public static List<String> readFileAsList(String fileName) {
    try (Stream<String> input = Files.lines(Paths.get(fileName))) {
        return input
            .map(String::strip)        // убрать пробелы (Java 11)
            .filter(s -> !s.isEmpty()) // отфильтровать пустые строки
            .collect(Collectors.toList());
    } catch (IOException ioex) {
        throw new RuntimeException("Не смог прочитать файл: " + fileName, ioex);
    }
}

Получить же двумерный массив строк из двумерного списка достаточно тривиально:

public static String[][] toMatrix(List<List<String>> data) {
    return data.stream() // Stream<List<String>>
        .map(list -> list.stream().toArray(String[]::new)) // Stream<String[]>
        .toArray(String[][]::new);
}

Или же более короткая запись в операции map с использованием метода List::toArray(T[] arr):

// ...
        .map(list -> list.toArray(new String[0]))

Тест:

List<List<String>> aaa = Arrays.asList(
    Arrays.asList("aaa", "bbb", "ccc"),
    Collections.emptyList(),
    List.of("11", "22")
);
System.out.println("список: " + aaa);

System.out.println("список: " + Arrays.deepToString(toMatrix(aaa)));

Результат:

список: [[aaa, bbb, ccc], [], [11, 22]]
массив: [[aaa, bbb, ccc], [], [11, 22]]