0

While using nextInt() method of Java, I came across this code:

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

I know that string1 would contain an empty string. My question is why calling nextLine method twice like following gives error:

String string1 = scan.nextLine().nextLine();
  • 3
    Because `nextLine` returns a `String` and that doesn't have a `nextLine` member function. – 001 Sep 10 '18 at 15:12
  • `Scanner#nextLine` returns a _string_, not another `Scanner` object. Chaining doesn't make good sense here; you want to use the string value which gets returned. – Tim Biegeleisen Sep 10 '18 at 15:13
  • (Adding on to the existing comments) generally speaking, you may see this phenomenon called a "terminal operator" or "terminal operation" - it means that a method returns an object which doesn't have many or any useful options for continuing the stream or chain. It's definitely a more common term when using Streams, but the concept is global. – Jeutnarg Sep 10 '18 at 15:18
  • I appreciate the comeback! – GhostCat Feb 11 '19 at 15:59

4 Answers4

8

Here:

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

Lets break it up:

String string1 = scan.nextLine()

calls nextLine() on a scanner. It returns a String.

Thus, your code boils down to

String string1 = someOtherString.nextLine(); 

which, of course, can't work. Because the String class has no idea about a next line, and therefore no such method!

Remember: the scanner returns a string, and these are two very different objects.

If you take an egg out of a box, why would you expect that you can take another egg out of that egg you got?! You can take two eggs out of the same box, but not an egg out of an egg.

Finally: yes, there is the idea "fluent" APIs, that allow for chaining method calls in "such" ways. But that can only work for scenarios that are explicitly designed for exactly that.

GhostCat
  • 137,827
  • 25
  • 176
  • 248
1

How to Debug This?

I think what's more important than a simple answer is some info on how to debug this.

Assuming you're in an IDE like IntelliJ or Eclipse, they have rich features for this (googling them is easy).

For IntelliJ for example:

  • ctrl + q on a method name will show you its return type and information about it.
  • If you just write the first method call on a line, you can do alt + enter and tell it to create the local variable. This will do it for the correct type (which would have been String, making it obvious.
  • You can also do ctrl + b to jump into the function call and see that it returns a String clearly.
  • Also, the debugger would have made it pretty obvious.

Java Doc

Also, you could always jump to the Java doc for scanner in google pretty easily.

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

Actually, the Java docs are often available or downloadable in your IDE when you jump into the functions with ctrl + b which saves you even using a browser :).

Basic Answer

But in any case, your issue here is just that the first function call returns a String, which isn't a scanner, so you can't use the scanner function on it :).

John Humphreys
  • 37,047
  • 37
  • 155
  • 255
  • I agree that such information is helpful. But well, there are zillions of things a newbie should/could know about, in order to be more efficient with his learning activities. From that PoV, we could reject 99,9% of all questions here as duplicate to an answer that explains "how to debug stuff". – GhostCat Sep 10 '18 at 15:22
  • I wasn't discounting your answer, I was actually probably the first one to mark it up :) - it's the right one. But he's a first-time user and I think it helps to provide some general debugging help even if the question isn't stellar. I definitely posted a few of these back in the day, and a little intro to basic debugging can go a long way for someone. If it helps someone learn its worth it :). But yeah... if it wasn't a first time user I would have flagged this one for deletion. – John Humphreys Sep 10 '18 at 15:29
  • I didnt downvote, to the contrary ... just saying, thats all ;-) – GhostCat Sep 10 '18 at 15:33
  • 1
    I didn't think you did! :) – John Humphreys Sep 10 '18 at 15:51
1

Ref: Why is nextLine() returning an empty string?

scannerObj.nextInt() doesn't read the following new-line character, so the first nextLine (which returns the rest of the current line) will always return an empty string.

This should work:

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

String input=readInput.nextLine();
Ashvin solanki
  • 4,802
  • 3
  • 25
  • 65
  • Not really his question. He's asking why he can't call `nextLine()` on the String returned by the first `nextLine()`, which is covered by the other answers. – Justin Reeves Sep 10 '18 at 15:27
  • 1
    It seems you only read the title of the question. Your point is valid, but not answering the question. – GhostCat Sep 10 '18 at 15:27
  • @GhostCat Thanks For Pointing out me I will Edited My answer and Make Help full as Possible Again ThankYou – Ashvin solanki Sep 10 '18 at 15:51
0

Look at the return type of Scanner#nextLine(). It returns a String, not a Scanner.

What you wrote is equivalent to:

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

Method Chains are for jumping from one object to the next as defined by each method's return type, making your code more compact and reducing the amount of declarations you make.

Justin Reeves
  • 1,148
  • 10
  • 24