1

In class java.util.Scanner,method public String next() finds and returns the next complete token from this Scanner,I am confused,if I write a program like this:

public static void main(String[] args) {
    Scanner in = new Scanner(System.in);
    System.out.println(in.next());
    in.close();
}

and run this program,then input a word and the word will be printed,it seems that method next() returns the current token,why does the API say next() returns the next complete token?

Jordi Castilla
  • 26,609
  • 8
  • 70
  • 109
Lemuel Lee
  • 83
  • 1
  • 8

3 Answers3

2

I will describe what all of this is about, since you are confused.

Scanner input = new Scanner(System.in) 

java.lang.System is a public final class extending java.lang.Object and it has static fields namely err and out being of type PrintStream and in being of type InputStream hence,

System.in

java.util.Scanner extends java.lang.Object and implements the following interfaces:

  • Iterator
  • Closeable
  • AutoCloseable

Now that we understood the hierarchy. What happens during execution?

Execution of > Scanner input = new Scanner(System.in)

Constructs a new Scanner object passing it the source through which it should expect the input.

Execution of > input.next() 

does the following steps

  • Block execution while waiting for input to scan

As soon as you provide an input (assume below)

"Hello World! This is a test." 

and hit Enter the following steps take place

  • Scanner read the data from Input Stream
  • Tokenizes the input using the delimiter (default whitespace)
  • Construct an iterator similiar to Iterator iterate = tokens.iterator() for iteration through tokens
  • Find the first complete token being "Hello" in the scanner, returns the token and waits before next token.

The reason the first complete token is returned is because that is how next() method that is inherited from java.util.Iterator behaves. Basically think of it a pointer pointing to bunch of tokens in scanner arranged in an order. As soon as next() is invoked, returns first token and moves the pointer ahead.

hasNext() on the other hand, returns true if this scanner has another token from the location the iterator is pointing to. Unlike next() it does not advance past the token.

The documentation says the following about next()

Finds and returns the next complete token from this scanner. A complete token is preceded and followed by input that matches the delimiter pattern. This method may block while waiting for input to scan, even if a previous invocation of hasNext() returned true.

Raf
  • 7,505
  • 1
  • 42
  • 59
  • Thank you very much. I've checked the documentation of interface ListIterator: http://docs.oracle.com/javase/8/docs/api/, now I'd like to ask is the cursor position before the first element in a list like a virtual head point of a list? – Lemuel Lee Nov 21 '15 at 01:55
  • The way I understand it is, the cursor points to the head of the list being first element. When next() is called, cursor moves and point to the next element in the list ... that's why it is called next() because it moves the cursor to next position and whatever element it was pointing to before is returned. – Raf Nov 21 '15 at 10:29
  • 1
    @JordiCastilla thanks for the compliment. The question helped me do some research and learn also. – Raf Nov 21 '15 at 14:39
1

This is because you assigned the Scanner to standart input (System.in).

If you use your exact program in this

IDEONE DEMO

OUTPUT (check in the link how stdin is assigned prior to execute)

Success!

stdin  // this is what you assign
    hello word

stdout  // this is the output of main method
    hello
    word

If this does not clarify, maybe you will find this example useful. Check how I assign the Scanner to a created String:

String input = "hello my name is Jordi";
Scanner s = new Scanner(input);    // assign the scanner to String s!!!!
System.out.println(s.next());      // prints: hello
System.out.println(s.next());      // prints: my
System.out.println(s.next());      // prints: name
System.out.println(s.next());      // prints: is
System.out.println(s.next());      // prints: Jordi
s.close(); 
Community
  • 1
  • 1
Jordi Castilla
  • 26,609
  • 8
  • 70
  • 109
  • is next of standard input, if your input is after execution, this next() wait for standard input for some text, if you check the ideone demo I created you will see clearer, – Jordi Castilla Nov 20 '15 at 12:03
  • Thank you.I've checked the ideone demo,I'm still confused why the first world "hello" is a next? – Lemuel Lee Nov 20 '15 at 12:11
  • again, because you assigned to Standart in and standart in has not been still created in your execution, if you look the demo, the standard in is assigned before execute, so, next() is clearer.... This is the expected behaviour to make compatible prior created and post created inputs – Jordi Castilla Nov 20 '15 at 12:16
0

You can think, that initially Scanner point on the beginning of the string, then when you call next() it reads starts from the current position. Like this:

[h][e][l][l][o][_]
^

Scanner behave similar to iterators and starts "before" first character.

saroff
  • 688
  • 9
  • 20
  • Thank you.Then is the start point of Scanner like a virtual head point of a list? – Lemuel Lee Nov 21 '15 at 01:47
  • @LemuelLee yep, close to it. Read about how Iterators work. In short - they are starts "before" the first element, when you call next() they are step over next element (in this case, first element), returns it, and now iterator itself point's "between" first and second element. Ofcourse, there is no special objects for "before" and "between" elements, It's just an abstraction, that makes it easier to think about. – saroff Nov 22 '15 at 10:28