Как разделить поток строк и создать список массивов строк? - PullRequest
0 голосов
/ 03 января 2019

Я довольно плохо знаком с потоками, поэтому, пожалуйста, помогите мне (и будьте нежны).

Я хотел бы сделать следующее.У меня есть BufferedReader, который читает из файла, в котором каждая строка выглядит примерно так: «a, b».Например:

Пример входного файла

"a, b"

"d, e"

"f, g"

Я хотел бы преобразовать это в LinkedList<String[]>:

Пример LinkedList<String[]>

[{" a "," b "}, {"c", "d"}, {"f", "g"}]

Как бы вы это сделали, используя потоковый подход?

Вот что я пробовал:

List numbers = reader.lines().map(s -> s.split("[\\W]")).collect(Collectors.toList());

Это не работает.Моя IDE предоставляет следующую обратную связь:

Incompatible types. Required List but 'collect' was inferred to R: no instance(s) of type variable(s) T exist so that List<T> conforms to List

Показывает ... Я все еще пытаюсь вычислить потоки.

Ответы [ 3 ]

0 голосов
/ 03 января 2019

Во-первых, я бы рекомендовал избегать использования необработанных типов и вместо этого использовать List<String[]> в качестве типа получателя.

List<String[]> numbers = reader.lines()
                               .map(s -> s.split(delimiter)) // substitute with your deilimeter
                               .collect(Collectors.toList());

Вы упомянули, что хотите реализацию LinkedList.вы почти всегда должны отдавать предпочтение ArrayList, которое toList возвращает по умолчанию в настоящее время , хотя это не гарантируется, поэтому вы можете указать реализацию списка явно с помощью toCollection:

List<String[]> numbers = reader.lines()
                               .map(s -> s.split(delimiter)) // substitute with your deilimeter
                               .collect(Collectors.toCollection(ArrayList::new));

и аналогично для LinkedList:

List<String[]> numbers = reader.lines()
                               .map(s -> s.split(delimiter)) // substitute with your deilimeter
                               .collect(Collectors.toCollection(LinkedList::new));
0 голосов
/ 03 января 2019

Предполагая, что каждая строка представляет собой кортеж из 2 элементов, вы можете собрать их в Список чего-то, что выглядит как кортеж из 2 элементов.Обратите внимание, что Java не имеет собственного типа для кортежей (например, Scala или python), поэтому вы должны выбрать способ представления элементов.

вы можете создать список записей:

List<Map.Entry<String, String>> numbers = 
                 reader.lines()
                       .map(s -> s.split(","))
                       .map(a -> new AbstractMap.SimpleEntry<>(a[0], a[1]))
                       .collect(Collectors.toList());

или список строк:

List<String> numbers = reader.lines()
                             .map(s -> s.split(","))
                             .map(a -> "{" + a[0] + "," + a[1] + "}"))
                             .collect(Collectors.toList());

Обратите внимание, что, как правило, вы не хотите придерживаться определенной реализации списка, когда вы собираете поток, хотя в некоторых случаях вам это может понадобиться.В этом случае укажите поставщика сбора для использования с toCollection(LinkedList::new) вместо toList()

0 голосов
/ 03 января 2019

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

Path path = Paths.get("src/main/resources", "data.txt");
try (Stream<String> lines = Files.lines(path)) {
    List<String> strings = lines.flatMap(l -> Arrays.stream(l.split(","))).map(String::trim)
        .collect(Collectors.toCollection(LinkedList::new));
}

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

...