Почему я не могу дважды вызвать метод nextLine() в java?

При использовании метода nextInt() для Java я наткнулся на этот код:

Scanner scan = new Scanner(System.in);
int count = scan.nextInt();
String string1 = scan.nextLine();

Я знаю, что string1 будет содержать пустую строку. Мой вопрос в том, почему вызов метода nextLine дважды, как показано ниже, дает ошибку:

String string1 = scan.nextLine().nextLine();

person Sanket Jain    schedule 10.09.2018    source источник
comment
Поскольку nextLine возвращает String и у него нет функции-члена nextLine.   -  person Johnny Mopp    schedule 10.09.2018
comment
Scanner#nextLine возвращает строку, а не другой объект Scanner. Цепочка здесь не имеет смысла; вы хотите использовать строковое значение, которое возвращается.   -  person Tim Biegeleisen    schedule 10.09.2018
comment
(Добавляя к существующим комментариям) вообще говоря, вы можете увидеть это явление, называемое терминальным оператором или терминальной операцией - это означает, что метод возвращает объект, у которого не так много полезных опций для продолжения потока или цепочки. Это определенно более распространенный термин при использовании потоков, но концепция носит глобальный характер.   -  person Jeutnarg    schedule 10.09.2018
comment
Я ценю возвращение!   -  person GhostCat    schedule 11.02.2019


Ответы (4)


Здесь:

String string1 = scan.nextLine().nextLine();

Давайте разобьем:

String string1 = scan.nextLine()

звонит nextLine() на сканер. Он возвращает String.

Таким образом, ваш код сводится к

String string1 = someOtherString.nextLine(); 

что, конечно, не может работать. Потому что класс String понятия не имеет о следующей строке и, следовательно, не имеет такого метода!

Помните: сканер возвращает строку, а это два совершенно разных объекта.

Если вы берете яйцо из коробки, то почему вы ожидаете, что сможете взять еще одно яйцо из того яйца, которое у вас есть?! Вы можете взять два яйца из одной коробки, но не яйцо из яйца.

Наконец: да, есть идея «свободных» API, которые позволяют связывать вызовы методов «такими» способами. Но это может работать только в сценариях, специально предназначенных именно для этого.

person GhostCat    schedule 10.09.2018

Как это отладить?

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

Предполагая, что вы используете IDE, такую ​​​​как IntelliJ или Eclipse, у них есть богатые возможности для этого (их легко найти в Google).

Например, для IntelliJ:

  • ctrl + q на имени метода покажет вам тип возвращаемого значения и информацию о нем.
  • Если вы просто напишете первый вызов метода в строке, вы можете сделать alt + enter и сказать ему создать локальную переменную. Это сделает это для правильного типа (который был бы String, что делает его очевидным.
  • Вы также можете сделать ctrl + b, чтобы перейти к вызову функции и убедиться, что она четко возвращает String.
  • Кроме того, отладчик сделал бы это довольно очевидным.

Документация по Java

Кроме того, вы всегда можете легко перейти к документу Java для сканера в Google.

https://docs.oracle.com/javase/7/docs/api/java/util/Scanner.html#hasNextLine()

На самом деле, документы Java часто доступны или загружаются в вашей среде IDE, когда вы переходите к функциям с помощью Ctrl + B, что избавляет вас даже от использования браузера :).

Основной ответ

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

person John Humphreys    schedule 10.09.2018
comment
Согласен, такая информация полезна. Но есть масса вещей, о которых новичок должен/мог бы знать, чтобы быть более эффективным в своей учебной деятельности. Из этого PoV мы могли бы отклонить 99,9% всех вопросов здесь как дубликаты ответа, который объясняет, как отлаживать вещи. - person GhostCat; 10.09.2018
comment
Я не обесценивал ваш ответ, я, вероятно, был первым, кто его отметил :) - это правильно. Но он новый пользователь, и я думаю, что это помогает предоставить некоторую общую помощь по отладке, даже если вопрос не звездный. Я определенно опубликовал несколько из них в свое время, и небольшое введение в основы отладки может иметь большое значение для кого-то. Если это поможет кому-то узнать, оно того стоит :). Но да... если бы это был не первый пользователь, я бы пометил его для удаления. - person John Humphreys; 10.09.2018
comment
Я не минусовал, наоборот ... просто сказал, вот и все ;-) - person GhostCat; 10.09.2018
comment
Я не думал, что ты сделал! :) - person John Humphreys; 10.09.2018

Ссылка: Почему nextLine() возвращает пустую строку?

scannerObj.nextInt() не читает следующий символ новой строки, поэтому первая строка nextLine (которая возвращает оставшуюся часть текущей строки) will always return an empty string.

Это должно работать:

int count = readInput.nextInt();
readInput.nextLine();

String input=readInput.nextLine();
person Ashvin solanki    schedule 10.09.2018
comment
Не совсем его вопрос. Он спрашивает, почему он не может вызвать nextLine() для строки, возвращаемой первым nextLine(), которая охватывается другими ответами. - person Justin Reeves; 10.09.2018
comment
Кажется, вы только прочитали название вопроса. Ваша точка зрения верна, но не отвечает на вопрос. - person GhostCat; 10.09.2018
comment
@GhostCat Спасибо, что указали на меня. Я отредактирую свой ответ и сделаю справку максимально полной. Спасибо. - person Ashvin solanki; 10.09.2018

Посмотрите на возвращаемый тип Scanner#nextLine(). Он возвращает String, а не Scanner.

То, что вы написали, эквивалентно:

String string1 = scan.nextLine();
String string2 = string1.nextLine();

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

person Justin Reeves    schedule 10.09.2018