Where is the keyboard specified the System.in method? - java

I can't conceptually understand in the below code (that retrieves characters from keyboards and prints to the command line) where I specified that input must come from the keyboard?
public class Adder
{
public static void main(String arr[])
{
//Explain this next line, please:
Scanner in = new Scanner(System.in);
System.out.println("Enter First No.");
int a = in.nextInt();
System.out.println("Enter Second No.");
int b = in.nextInt();
int c = a+b;
System.out.println("Sum is: "+c);
}
}

System.in isn't a method, it's a field that's tied to your keyboard by default.
The "standard" input stream. This stream is already open and ready to supply input data. Typically this stream corresponds to keyboard input or another input source specified by the host environment or user.
You can call the System.setIn(InputStream in) method to change it to a different input stream.
Reference: I/O from the Command Line

Scanner sc = new Scanner(System.in);
Lets break it down
Scanner: The Scanner class is a class in java.util, which allows the user to read values of various types
System.in: An InputStream which is typically connected to keyboard input of console programs
Scanner S = new Scanner(System.in)
above line will invoke Constructor of Scanner class with argument System.in, and will return a reference to newly constructed object.
S is connected to a Input Stream that is connected to Keyboard, so now at run-time you can take user input to do required operation.
further study:
Scanner (Java Platform SE 8)
let me know, if you have any confusion.

Related

Can I input all the command at once?

I implemented a java program with some methods. Next I created a main class which will call the related method by entering a word.
for example:
Enter {A|B|C|D|E} to call method. A=method one B = method two...etc
A<--this is the user input
Enter Number:<--the first Scanner input of method A
123<--Input 1
Enter words:<-- the second Scanner input of method A
ABC<--Input 2
123ABC<--The output method A
Enter {A|B|C|D|E} to call method. A=method one B = method two...etc
B<--this is the user input
Enter Number 1:<--the first Scanner input of method B
100<--Input 1
Enter Number 2:<-- the second Scanner input of method B
50<--Input 2
150<--The output method B
Code of Method A {
String output;
private static Scanner keyboard = new Scanner(System.in);
System.out.println("Enter Number:");
String no = keyboard.nextLine();
System.out.println("Enter Words:");
String words = keyboard.nextLine();
//do something...
System.out.println(output);
}
Code of Main class{
private static Scanner keyboard = new Scanner(System.in);
public static void main(String[] args){
Main main = new Main();
main.run();
}
public void run() {
boolean running = true;
while (running) {
displayMenu();
String command = keyboard.nextLine();
String[] parts = command.split("^");
if ("A".equalsIgnoreCase(command)) {
//call method A
} else if ("B".equalsIgnoreCase(command)) {
//call method B
} else if....etc
System.out.println();
}
what I want is input
A123 , ABCB100,50 at once
then the system will print the output of method A (123ABC) and B (150) for me.
What I want is input A into "keyboard", input 123 into "no" and input ABC into "words" at once
How can I do it?
As long as your don't close your Scanner (or its underlying input stream), the yet-to-read tokens will remain accessible for later use : read two lines (or 4 tokens - the comma is one) and "B\n100,50" will remain.
If you're asking how to provide this kind of input, it depends on your invokation method. If executed from bash, I'd use the following :
echo """A
123 , ABC
B
100,50""" | java ...
If you're asking how to dynamically invoke a method from its name, check the reflection API. Oracle's tutorial is a good resource in my opinion, here's a link to its section on retrieving and invoking methods.
There are 2 ways to do that.
First:
Instead of giving input directly in the console, first write all the data input somewhere and just copy it and paste it in the console.
Second:
You can use hasNexLine() and send EOF through keyboard by pressing ctrl+d.
Code:
public static void main(String[] args)
{
Scanner s = new Scanner(System.in);
StringBuilder sb = new StringBuilder();
while(s.hasNextLine())
{
sb.append(s.nextLine());
}
System.out.println(sb.toString());
}
Provide all your input and press ctrl+d to stop taking input.

Scanner continuous loop

Why isn't my inputScanner blocking after the first input? It goes into a continous loop. Ignore other details of this code.
public class Test {
public static void main(String[] args) {
boolean finished;
do {
Scanner inputScanner = new Scanner(System.in);
finished = inputScanner.hasNext("exit");
boolean validNumber = inputScanner.hasNextDouble();
if (validNumber) {
double number = inputScanner.nextDouble();
System.out.print(number);
} else if (!finished) {
System.out.println("Please try again.");
}
inputScanner.close();
} while (!finished);
}
}
EDIT: On a previous post which was related to this, it was mentioned that "So if you are going use System.in later don't close it (if it is closed, we can't reopen it and read any data from it, hence exception)". Why is this happening?
Why isn't my inputScanner blocking after the first input?
Because you're creating a new Scanner each time you enter the loop, so it's not the same object on 1st iteration than in 2nd and further iterations
public class Test {
public static void main(String[] args) {
boolean finished;
do {
Scanner inputScanner = new Scanner(System.in); //Here you're making a new instance of inputScanner each time you come to this line after the do-while loop ends.
finished = inputScanner.hasNext("exit");
boolean validNumber = inputScanner.hasNextDouble();
if (validNumber) {
double number = inputScanner.nextDouble();
System.out.print(number);
} else if (!finished) {
System.out.println("Please try again.");
}
inputScanner.close();
} while (!finished);
}
}
If you want it to be "blocked" or "closed", then move this line before the do { line.
Scanner inputScanner = new Scanner(System.in);
For your second question:
So if you are going use System.in later don't close it (if it is
closed, we can't reopen it and read any data from it, hence exception)
From Oracle's docs:
"Attempting to perform search operations after a scanner has been
closed will result in an IllegalStateException"
It's like trying to make a dead person to do something, it would be like a zombie! (And Java hates zombies!) D:
But you're not getting that IllegalStateException because as I said on the answer for your 1st question, you're making a new object each time you go into the do-while loop.
Edit
Why can't you reopen it? Also from Oracle's docs:
When a Scanner is closed, it will close its input source if the source
implements the Closeable interface.
Thus inputScanner.close() closes System.in.
And because of the general contract for OutputStream's close (with the help of this answer):
public void close() throws IOException --> Closes this input stream and releases any system resources associated with this stream. The general contract of close is that it closes the input stream. A closed stream cannot perform input operations and cannot be reopened.
If you take a look at documentation of Scanners methods like hasNext(String) or hasNextDouble you will see that it
Throws:
IllegalStateException - if this scanner is closed
(emphasis mine)
So to throw IllegalStateException you first need to close Scanner, not stream from which it is reading data.
So lets take a look at this example:
Scanner sc = new Scanner(System.in);
System.out.println("type something:");
System.out.println(sc.hasNext());// true
System.out.println("your data: "+ sc.nextLine());
sc.close();
System.out.println("type something:");
System.out.println(sc.hasNext());// throws java.lang.IllegalStateException: Scanner closed
Last line throws IllegalStateException because you are invoking hasNext method on closed scanner (so we know that after invoking sc.close() stream from which it reads must be also closed so we can safely assume that there are no more elements to read, or since stream was closed we may not be allowed to read it).
Now if we don't close scanner but close System.in we will still be able to use this instance of scanner without getting exceptions. So lets simply change sc.close(); to System.in.close() (I will skip exceptions handling for simplicity):
Scanner sc = new Scanner(System.in);
System.out.println("type something:");
System.out.println(sc.hasNext());// true
System.out.println("your data: "+ sc.nextLine());
System.in.close();
System.out.println("type something:");
System.out.println(sc.hasNext());// false
As you can see there is no exception here because it wasn't scanner which was closed, but stream which scanner which was being read.
Why closing System.in doesn't cause scanner to throw exception?
I suspect that decision to not throw exception here was made with assumption that exception symbolize problem with code. If programmer allowed scanner to being closed he should also make sure that this particular closed instance of scanner will not be used anywhere.
Now returning false instead of throwing exception is normal reaction where there is no more elements to read. So if stream which scanner was reading was closed naturally (like when we read text file and read its last line so there is nothing more to read) scanner handles this situation like something normal (so there is no need to point that this is some exceptional situation).
Now in your loop you are kind of combining these two scenarios. Your code can be simplified to something like:
Scanner sc = new Scanner(System.in);
System.out.println("type something:");
System.out.println(sc.hasNext());// true
System.out.println("your data: "+ sc.nextLine());
System.in.close();
sc = new Scanner(System.in);//IMPORTANT
System.out.println("type something:");
System.out.println(sc.hasNext());// false
As you see in line
sc = new Scanner(System.in);//IMPORTANT
you are creating new instance of scanner which wasn't closed yet, so its hasXYZ methods always returns false because System.in can't provide no more values.
Additional trap
One problem which I didn't mentioned earlier is fact that in case of wrong input, which is neither "exit" nor double if you are are not consuming that invalid cached value from scanner by using any of nextXZY methods like hasNext("exit") or hasNextDouble will be still based on that invalid data, like:
Scanner sc = new Scanner("foo 1");
System.out.println(sc.hasNextInt());//false because `foo` is not integer
System.out.println(sc.hasNextInt());//also false because we are still
//reading `foo` which is not integer
String str = sc.next();//lets read (sonsume) foo
System.out.println(sc.hasNextInt());//true since 1 is integer
Solution
Simplest solution to such problem is creating only one instance of Scanner which will handle System.in and reuse it in your entire application. Then at the end of your application you can decide to close your scanner or System.in.
So your code can look like:
boolean finished;
Scanner inputScanner = new Scanner(System.in);
do {
finished = inputScanner.hasNext("exit");
boolean validNumber = inputScanner.hasNextDouble();
if (validNumber) {
double number = inputScanner.nextDouble();
System.out.print(number);
} else if (!finished) {
System.out.println("Please try again.");
inputScanner.next();// lets not forget to consume from scanner cached
// invalid data which is neither double or "exit"
}
} while (!finished);
inputScanner.close();

How to properly close a Scanner class inside a method?

I have this code that calls to a method in order to check if a number is a certain length, and if not, a new number should be reintroduced by the user.
Problem here is, I can't find the proper way to close a Scanner class in order to prevent a resource leak.
Here's the code so far.
public static void setIdentification(Person p, int dni) {
Scanner input = new Scanner (System.in);
String lengthChecker = Integer.toString(dni);
if (lengthChecker.length() < 1 || lengthChecker.length() > 8) {
int dni1;
do{
System.out.println("The ID number isn't valid. Please, introduce a valid number: ");
dni1 = input.nextInt();
lengthChecker = Integer.toString(dni1);
} while (lengthChecker.length() > 8 || lengthChecker.length() < 1 );
p.dni = dni1;
} else {
p.dni = dni;
}
}
public static void main(String[] args) {
Scanner input1 = new Scanner (System.in);
int dni = input1.nextInt();
Person person1 = new Person();
setIdentification(person1, dni);
}
I have tried to set the input.close(); in a number of different locations but I always end up getting a run-time error.
There's probably a million ways to optimize this code but right now I'm just really curious as to how to get those Scanners closed.
#Jules is correct. In this case, it is neither necessary or advisable to close the Scanner.
But assuming that you did, then the recommended way to do it is this:
try (Scanner input1 = new Scanner (System.in)) {
int dni = input1.nextInt();
Person person1 = new Person();
setIdentification(input1, person1, dni);
}
... noting that you must change your setIdentification method so that it doesn't attempt to open its own scanner. Creating multiple scanners for the same input stream is a mistake. Indeed, it is the mistake in your code.
This works for Java 7 and later. (Under most circumstances, you should not be writing new code for older versions of Java. Android is an exception, because support for Java 7 extensions has only recently become available in Android toolchains.
So why can't you open and close multiple scanners on the same stream? Two reasons:
When you close a Scanner, you automatically close the underlying stream. That means if you then attempt to open / use another scanner on the stream, it will fail when you attempt to read from the closed stream. Streams cannot be reopened.
Even if you don't close the scanner / stream, creating a second scanner on a stream is likely to lead to trouble. A scanner has to read ahead in order to figure out where the token boundaries are. It then keeps any read-ahead characters in an internal buffer. Each scanner has its own buffer. So if you have two or more scanners for the same stream, and interleave their use, one scanner is liable to "grab" characters that the other scanner needs.
Closing your scanner will close the input stream it was created using. In your case, this is System.in. This stream is a special case: it is opened by the environment before your program starts running, and therefore should not usually be closed by your program.
In this case, it's fine to not close your Scanner. Just let the garbage collector deal with it.

"Given 2 ints, a and b, return true if one if them is 10 or if their sum is 10." How can I apply real numbers

package cornett1;
import java.util.Scanner;
public class CodeRat {
public static boolean makes10(int a , int b)
{
return (a + b == 10 || a == 10 || b == 10);
}
public static void main (String[] args) {
Scanner s = new Scanner(System.in);
System.out.print(makes10(s.nextInt(),s.nextInt());
}
}
I am using a website called codingbat to do programming exercises and I solved the question
"Given 2 ints, a and b, return true if one of them is 10 or if their sum is 10." How can I apply this program and Input actual numbers.
Write a main method in the class, and pass in two numbers when invoking the program.
In the main method, Use
int a = Integer.parseInt(argument 0);
int b = Integer.parseInt(argument 1);
Now create a new instance of JOption class and invoke the method 'makes10' in the method with the arguments.
JOption opt = new JOption();
boolean answer = opt.makes10(a, b);
System.out.println(answer);
One of the easiest option you have is
java.util.Scanner
Defention: A simple text scanner which can parse primitive types and strings
using regular expressions.
A Scanner breaks its input into tokens
using a delimiter pattern, which by default matches whitespace.
The resulting tokens may then be converted into values of different types
using the various next methods.
Why using Scanner API?
1. A Scanner breaks its input into tokens using a delimiter pattern, which by default matches whitespace.
2. A scanning operation may block waiting for input.
3 .A Scanner is not safe for multithreaded use without external synchronization.
For example:
Scanner input = new Scanner(System.in);
int i = sc.nextInt();
System.out.println("the number you entered is " + i);
Explanation:
you read from console and feed scanner variable which is input and you just want to read int. at the end, you print the read number on the console
Resources
first one
second one
Another option is using BufferedReader API
Reads text from a character-input stream, buffering characters so as
to provide for the efficient reading of characters, arrays, and lines.
The buffer size may be specified, or the default size may be used. The
default is large enough for most purposes.
take a look at this sample for your BufferReader need
BufferReader vs Scanner
BufferedReader has significantly larger buffer memory than Scanner. Use BufferedReader if you want to get long strings from a stream, and use Scanner if you want to parse specific type of token from a stream.
Scanner can use tokenize using custom delimiter and parse the stream into primitive types of data, while BufferedReader can only read and store String.
BufferedReader is synchronous while Scanner is not. Use BufferedReader if you're working with multiple threads.
In your case:
int a = 0;
int b = 0;
Scanner input = new Scanner(System.in);
System.out.println("Please enter two numbers");
a = input.nextInt();
b = input.nextInt();
JOption jp = new JOption();
jp.makes10(a, b);
}
public boolean makes10(int a, int b) {
return ((a + b) == 10 || a == 10 || b == 10);
}
Read up on this:
http://docs.oracle.com/javase/tutorial/essential/environment/cmdLineArgs.html
This tells you how to take arguments form the command line and use those as variables in your program.
public static void main (String[] args) {
int a = Integer.parseInt(args[0]);
int b = Integer.parseInt(args[1]);
System.out.print(makes10(a,b));
}
If you want input at runtime, you can use the Scanner class or the Console class
Scanner s = new Scanner(System.in);
System.out.print(makes10(s.nextInt(),s.nextInt()));
You can use a Scanner to get input from a user :
Scanner sc = new Scanner(System.in);
System.out.println(makes10(sc.nextInt(),sc.nextInt()));

Creating Two Scanners In Different Class

I am currently using two different scanners in my project in two separate classes: both take in user input that do different things. Calling the first scanner works normally, but when I try to call the second scanner, even after I've closed the first, it registers the input as null.
Class 1
Scanner scan = new Scanner(System.in);
public void foobar(){
System.out.println("Enter data: ");
String foo = scan.next();
scan.close();
class2.function(foo);
}
Class 2
Scanner scan1 = new Scanner(System.in);
public void foobar1(String foo){
System.out.println("Enter more data: ");
String fooo = scan1.Next();
//Automatically prints null here and closes program
}
Am I supposed to only use one Scanner somehow? Or do I use the Scanner class in some other manner? Thanks!
scan.close(); also closes System.in so that no more data can be read from the stream. So when you start reading from scan1, System.in will no longer return any data.
Therefore, don't close any Scanner instance until you're done with all the scanning if you're using the same input stream for all the instances.
Look at the docs of Scanner#close() for more info.
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 method will be invoked.
And if you look at the docs of System.in, you can see that it does implement the Closeable interface.
Thus the InputStream#close() is called and that closes the InputStream leaving you without a input stream to read data from.
Closes this input stream and releases any system resources associated with the stream.
No need to create two scanners, You can use same Scanner for both as once scan is closed Stream System.in also get closed.
like:
Scanner scan = new Scanner(System.in);
public void foobar(){
System.out.println("Enter data: ");
String foo = scan.next();
class2.function(foo,scan);
}
where:
public void function(String foo,Scanner scan1){
System.out.println("Enter more data: ");
String fooo = scan1.next();
System.out.println(fooo);
}
but still if you need to create two scanners use scan.reset(); instead of scan.close(); in class1

Categories

Resources