Попытка понять полное значение приведенного ниже оператора Stream.of (bufferedReader.readLine (). ReplaceAll ("\\ s $", "") - PullRequest
5 голосов
/ 16 июня 2020

Я добавляю снимок экрана для дополнительной информации. Я новичок в Java8, простите меня, если я задаю плохой вопрос. Когда я проводил исследование для ввода значений, разделенных пробелами, я получил это утверждение. Я понимаю, что приведенный ниже оператор принимает значение 1 2 3 и возвращает значение [1, 2, 3] в виде списка.

Пожалуйста, поправьте меня, если я ошибаюсь,

  • Stream: is используется в коллекции для итерации.

  • bufferedReader.readLine (): он читает строку как строку

  • replaceAll: заменяет пробел на , позже получает синтаксический анализ в Integer и собирается в List

Я сомневаюсь, когда я ввожу 1 2 3, который является строкой. Итак, этот поток сначала разделяет значение с пробелом, а затем повторяет разделенное значение? или это 1-й разбор значения, позже сохранение значения в списке, позднее разделение значения с пробелом и удаление пробела и замена на ,. Мне очень любопытно, как именно работает приведенный ниже оператор.

List<Integer> a = Stream.of(bufferedReader.readLine().replaceAll("\\s$", "").split(" "))
                .map(Integer::parseInt)
                .collect(toList());


  [1]: https://i.stack.imgur.com/nlXxd.jpg

Ответы [ 2 ]

8 голосов
/ 16 июня 2020
  • bufferedReader.readLine() читает одну строку как String. Строка не назначается ни одной переменной.
  • replaceAll("\\s$", "") закрепляется в конце строки и удаляет последний пробел. Было бы лучше использовать String#trim.
  • split(" ") разбивает строку на String[], разбивая ее на пробелы
  • Stream.of(String[]) берет String[], которые у нас есть, и возвращает Stream<String>
  • Stream<String>.map(Function<String, Integer>) преобразует Stream<String> в Stream<Integer>, применяя функцию сопоставления (Integer::parseInt) к каждому элементу потока
  • Stream<Integer>#collect(toList()) принимает a String<Integer> и собирает его в List<Integer>
  • List<Integer> a = ... присваивает результат вышеупомянутых шагов переменной a

И тогда все готово.

Запятая, которую вы видите при использовании System.out.println(a), создается путем вызова List#toString() (на самом деле, AbstractCollection#toString, который наследуется большинством реализаций List через Abstractlist), что дает список значений, разделенных запятыми, заключенный в квадратные скобки. Это строковое представление для удобства чтения нами, людьми, и не имеет ничего общего с тем, как список хранится внутри. Например, в ArrayList внутреннее хранилище будет Integer[], другие реализации списков используют другие структуры данных. Некоторые отладчики аналогичным образом показывают содержимое списков и массивов как списки, разделенные запятыми - это опять же чисто для удобства чтения.

1 голос
/ 16 июня 2020

Вы говорите, что

.replaceAll("\\s$", "")

заменяет пробел запятой, но это не то, что он делает. Он заменяет все вхождения пробела в конце строки ничем. (\s - это любой пробел, а $ - конец строки).

После этого строка разбивается на массив, разделителем которого является пробел: «». Затем все ячейки разбираются в целые числа и собираются в виде списка.

Замена кажется немного странной, но я не могу сказать, нужна она или нет, не зная контекста. Похоже, что обрезка подошла бы лучше

...