Привет!
По материалам первых лекций JR написал следующий код.
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
String s = "Люблю тебя, Петра творенье,\n" +
"Люблю твой строгий, стройный вид,\n" +
"Невы державное теченье,\n" +
"Береговой ее гранит";
System.out.println("Длина s = " + s.length() + " симолов");
Scanner scan = new Scanner(s);
while (scan.hasNext()) {
System.out.println(scan.nextLine());
System.out.println("внутри while");
}
scan.close();
}
}
Вывод получается такой:
Длина s = 105 симолов
Люблю тебя, Петра творенье,
внутри while
Люблю твой строгий, стройный вид,
внутри while
Невы державное теченье,
внутри while
Береговой ее гранит
внутри while
Таким образом.
s.length() -- честным образом сообщает нам, что s -- это объект типа String длинной 105 символов. Вполне понятно. Мало ли, что там есть символы перевода строки -- это ОДНА СТРОКА из такого вот набора разных символов.
А вот scan.nextLine() c какой-то радости считает, что это РАЗНЫЕ СТРОКИ.
Что видно в выводе.
Алогичность всегда пугает.
Почему это работает так странно?
Alex
2 уровень
Постигая непостижимую логику Java
Комментарии (8)
- популярные
- новые
- старые
Для того, чтобы оставить комментарий Вы должны авторизоваться
Justinian Judge в Mega City One Master
11 апреля 2021, 13:15
Что алогично, это то что ты не читаешь, для чего предназначен класс и метод, и при этом делаешь вывод что это алогичное поведение :)
Попробуй с консоли ввести эту строку на 105 символов, не забывай, что \n это Enter.
И поделись способом, как одним стандартным методом по вводу одной строки, например bufferedReader.readLine() ты сможешь ввести строку, нажав четырежды раз Энтер - за один вызов метода :)
Читай побайтово, и будет тебе честных 105 символов. За 105 раз.
Что такое Сканнер.
Это ТОКЕНИЗИРОВАННАЯ обертка, читающая с потоков.
Что значит "токенизированная", это значит, что сканнер как раз и используют для того, чтобы работать с этими /n, посмотри какие там методы:
nextBoolean, nextBigInteger, nextDouble, nextInt и тд.
Эта обертка и предназначена для случаев, когда у нас есть некоторая последовательность символов в буффере/ресурсе, а ты прыгаешь от одного токена к другому, от одной строки (а строка при чтении в ресурсе определяется двумя \n) к другой, от одного числа к другому.
Поэтому отличай строку как String объект в джаве и строку при чтении обертками. При побайтовом чтении, знак \n такой же знак как и все.
Но при использовании буфферизированных оберток, токенизированных, знак \n это разделитель строк.
И твоя строка, фактически это "хак", поскольку позволяет в одном объекте инкапсулировать несколько разных строк. Это удобно.
Да о чем мы говорим, просто выведи эту строку на экран и посчитай количество выведенных строк :) И скажи, выведется одна строка или несколько.
\n это символ переноса строк.
Ты просто изначально немножко запутался в понятии строка как объект, и понятии логической строки (то есть набор символов, которые находятся между знаками \n)
Буфферизированные обертки и токенизированные работают именно с логическими строками. Если тебе нужно работать с строкой как есть, ты просто используешь другие методы, читаешь побайтово например.
+6
Alex
12 апреля 2021, 00:20
Это очень глубокий ценный ответ. Спасибо тебе за него!
Что до того, что я "запутался" -- это элементарное размышление на тему дословного прочтения названий объектов и методов, а также той информации, которая есть в первых лекциях. Если бы эти материалы имели бы в себе хотя бы часть той глубины, что есть в твоём сообщении, -- ресурс несомненно выиграл бы.
+1
Justinian Judge в Mega City One Master
12 апреля 2021, 07:35
ну, по поводу запутался это я громко сказал, это уже можно было другие слова подобрать, но все ок, ты размышлял, спросил, получил ответ :)
Ресурс заточен под то, чтобы сделать из тебя программиста.
Изучение программирование мало чем отличается по сути от работы программистом, просто вопросы легче, минорнее, и нету рамок времени.
А принцип тот же, у тебя возникает вопрос, ты ищешь информацию, думаешь, размышляешь, не находишь ответ - спрашивает.
Поэтому ресурс и так выигрвает, с одной стороны короткие лекции, в которые нельзя поместить все, поскольку одному этого достаточно, второму нужен момент А там указать, третьему момент Б, четвертому момент В, можно было бы попробовать угодить всем, но каждая из сотен лекций занимала бы объем книги, и в итоге их бы не читали.
Поэтому ресурс джава раша представляет собой систему обучения.
Есть короткие лекции, которые многим достаточно (не забывай у всех разный уровень подготовки + люди учатся по разному, у кого-то возникают вопросы, у кого-то нет.)
Не достаточно лекций, часть вопросов покрывается в комментариях к лекциях, там и разъяснения и допматериалы и в Обсуждении задачи.
Не хватает регулярно теории, можно чуток посмотреть того же Алишева (лично я предпочитаю Головача, но для новичков наверное Алишев который содержимое лекций джава раша еще раз проговаривает на видео, как-то больше заходит судя по всему) или книги почитать Изучаем Джава или Шилдт/Хорстманн/Эккель, кому что заходит.
Если и при этом всем остались вопросы, есть раздел Помощь, в котором отвечают на все вопросы, связанные с джавой НЕЗАВИСИМО от задачи.
Ну и центр всего - практика, 1200 задач по джава кору, ничего не читая из книг, не спрашивая, если ты их решишь, то у тебя точно будут ответы на многие вопросы )
Так что как видишь все работает. +1
Alex
12 апреля 2021, 08:39
Спасибо!
Очень толково.
0
wan-derer.ru
11 апреля 2021, 07:36
А почему ты для считывания выбрал именно Scanner?
0
Alex
12 апреля 2021, 00:29
Можно было ещё спросить, почему для программирования я выбрал именно Java.
Написал же, что это работа с материалом первых лекций.
0
hidden #2322530
11 апреля 2021, 06:13
nextLine считывает следующую строку , критерием конца строки лявляется символ перевода строки
0
Alex
12 апреля 2021, 00:27
Вопрос, очевидно, был совершенно не про это.
А про то, почему s.length() и scan.nextLine() воспринимают конкретную строку так по-разному.
0