I want to know more about how next method work and Java utill scanner if someone can help me...
Scanner s = new Scanner(System.in);
System.out.println("Unesite string za proveru: ");
if(palindrom(s.next()))
System.out.println("String je palindrom");
else
System.out.println("String nije palindrom");
s.close();
what does next do? and how exactly scanner working also what means method close(); ??
next
public String next()
Finds and returns the next complete token from this scanner.A complete token is preceded and followed by input that matchesthe delimiter pattern. This method may block while waiting for input to scan, even if a previous invocation of hasNext() returned true.
Specified by:next in interface IteratorReturns:the next tokenThrows:NoSuchElementException
1 - if no more tokens are availableIllegalStateException
2- if this scanner is closedSee Also:Iterator
example :-
sc = "hello world"
1st time sc.next() output will be "hello"
2nd time sc.next() output will be "world"
close
public void close()
Closes this scanner.
If this scanner has not yet been closed then if its underlying readable also implements the Closeable interface then the readable's close methodwill be invoked. If this scanner is already closed then invoking thismethod will have no effect.
Attempting to perform search operations after a scanner hasbeen closed will result in an IllegalStateException.
Specified by:close in interface CloseableSpecified by:close in interface AutoCloseable
Scanner is a class that parses, and in some cases converts inputs. It uses whitespace as its default delimiter between tokens.
Scanner.next is a method that finds and returns the next token, if there is one.
Scanner.close is a method that releases the resource that the Scanner object is holding, such as an open file.
Related
This is from the Java's Scanner next() method explanation:
This method may block while waiting for input to scan, even if a
previous invocation of hasNext() returned true.
How can this method wait for user input to be entered if a call to hasNext() is made? If we call hasNext() and it returns true, we know that there is next token, so how and why the next() method does this?
You need to read the full documentation of the method:
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.
The Scanner#hasNext method (documentation) may return true when there is another token. But it could be possible that the token is not yet considered as complete according to the delimiter pattern and Scanner#next will always block until the the token is complete.
If there is a complete token in the Scanner then Scanner#next will immediately return and not block.
You can set the delimiter pattern by using the Scanner#useDelimiter method (documentation)
If you don't set a specific delimiter pattern than the Scanner will use a default pattern which matches whitespace characters.
As you have asked, blocked means that the method waits and does not return until the said event happened.
Consider this:
System.out.println("Before");
someBlockingMethod();
System.out.println("After");
With
public void someBlockingMethod() {
// Sleep for a second (ignoring exceptions for simplicity)
Thread.sleep(1000);
}
You will see After only once someBlockingMethod() has returned and this will only happen once the said event occurred. Thus the method blocks. In the example the method blocks for one second.
Scanner#next doesn't return a string until it has either reached the delimiter being used by the Scanner (whitespace is the default delimiter), or it has reached the end of the input stream.
If hasNext returns true, it means there is definitely more data in the input stream, but it may still need to block until it reaches the delimiter/EOF.
If you debug the following code, you will see that, actually, it is hasNext() method that is blocking and waiting for user input:
Scanner scanner = new Scanner(System.in);
if (scanner.hasNext()) {
String s = scanner.next();
}
That's because there is a blocking step inside hasNext():
public boolean hasNext() {
ensureOpen();
saveState();
while (!sourceClosed) {
if (hasTokenInBuffer())
return revertState(true);
readInput(); //THIS IS WAITING FOR USER INPUT
}
...
In case of console input, hasNext() waits till a complete token is entered and returns true, then subsequent next() invocation doesn't block.
In case of non-console input, hasNext() returns true even if there is not complete token, and subsequent next() invocation blocks and waits for complete token.
For the following code I have to put 2 inputs before I get to the ifstatement. Java is quiet new for me so I don't understand what I did wrong. Can anyone help me with solving this problem?
package oefenen;
import java.util.Scanner;
public class oefenen {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
String name;
System.out.println("Adin ne?");
// TODO Auto-generated method stub
name = scan.next();
if (scan.next().equals("samet")); {
System.out.println("Merhaba memetin oglu");
}
}
}
You ignore the value of name
And your if statement is actually being ignored as well due to the semicolon at the end
Try this
if (name.equals("samet")) { // remove semicolon
scan.next() will wait for new input each time you call it.
Try using name.equals("samet") instead of scan.next().equals("samet")
From the Scanner.next() doc :
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.
Every time you call next() method, it tries to read an input, in your example you called the method twice that's why you have to enter two inputs before you get to your print statement
public class Two {
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
int c=0;
while(sc.hasNext())System.out.println(++c+" "+sc.nextLine());
}
}
I came across this code and i want to confirm that by taking input directly without using object of any datatype all we are doing is taking input and displaying it and we are not storing it anywhere?
and also how is the condition inside while loop is true for the first time? As we have not given any input yet.
Sure, your code doesn't store sc.nextLine() , so this value will be discarded past the System.out.println instruction.
Also for hasNext() :
This method may block while waiting for input to scan.
so the condition will be met once the stream begins to provide input, and the method will block waiting for this to happen or an Exception to happen (e.g : if the Scanner gets closed ).
As long as nothing of those things happen, hasNext() method doesn't return, so the condition in while is still not evaluated, so the loop is blocked there .
Let's go through your code:
Scanner sc = new Scanner(System.in)
The java.util.Scanner.Scanner(InputStream) constructor is called, and you have an object sc of type Scanner which reads from System.in.
int c = 0;
You now have a primitive c of primitive type int.
while(sc.hasNext()) { ... }
The while loop evaluates sc.hasNext(), which is true. As per the documentation, sc.hasNext() returns true if and only if the input has another token in it. In your case, this means that the InputStream is open.
{... System.out.println(++c + " " + sc.nextLine()); ...}
sc.nextLine() is the problem. Assuming you have not changed System.in, the console/terminal will block the loop (i.e. hold the loop paused) until you give it an input (type in some text and hit [ENTER]).
So, overall:
Scanner::hasNext() will return true if and only if it is possible to get more input (if you are using System.in, this will always be true until you close the scanner).
If you are printing the input directly, you will not be storing any references to it, and no memory will be allocated for it (unless Scanner.nextLine() stores it somewhere).
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?
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.
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();
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.
I have made a program which is like a vending machine!
My code is similar to:
public static void main (String [] args) {
Scanner sc = new Scanner (System.in);
while(sc.hasNext()) {
String string = sc.next();
sum = generateSum(sum)
.....
}
}
public static int generateSum(int sum) {
Scanner sc = new Scanner (System.in);
while (sc.hasNext()) {
....
}
return sum;
}
Sorry for simplifying my code, but the normal one is very long! However, the problem is that I use while (sc.hasNext()) loop twice. Basically I want to continue my main method until the input from the user is TERMINATE, but my program terminates after running once.
I figured that if I take out my generateSum method, then the loop in my main method works fine so i guess it has to be something to do with have the while (sc.hasNext()) loop twice.
Any ideas how I can fix the problem?
The hasNext() method is going to block until you hit the end of file marker on System.in because it doesn't know if there's more input until it reads a full buffers worth or hits end of file (which you can signal with Control-Z on windows and Control-D on unix). At that point System.in is at the EOF mark and there's no way to re-open it from your code.
If you need to process multiple streams of data from System.in you are going to have to use some sort of sentinel value (such as the word END) to mark the end of one input stream and the beginning of another.
I'm quite sure that if you consume the input being scanned with sc.next() the state changes and hasNext() returns accordingly.The problem may be there.
The hasNext() method can be called as much as you want. But if in the inner loop you are calling the next() method, then that can eat the values from your outer loop.
So the inner loop most probably breaks after hasNext() is false and thus the outer loop also finishes.