NoSuchElementException Error in Java [duplicate] - java

This is meant to be a canonical question/answer that can be used as a
duplicate target. These requirements are based on the most common
questions posted every day and may be added to as needed. They all
require the same basic code structure to get to each of the scenarios
and they are generally dependent on one another.
Scanner seems like a "simple" class to use, and that is where the first mistake is made. It is not simple, it has all kinds of non-obvious side effect and aberrant behaviors that break the Principle of Least Astonishment in very subtle ways.
So this might seem to be overkill for this class, but the peeling the onions errors and problems are all simple, but taken together they are very complex because of their interactions and side effects. This is why there are so many questions about it on Stack Overflow every day.
Common Scanner questions:
Most Scanner questions include failed attempts at more than one of these things.
I want to be able to have my program automatically wait for the next input after each previous input as well.
I want to know how to detect an exit command and end my program when that command is entered.
I want to know how to match multiple commands for the exit command in a case-insensitive way.
I want to be able to match regular expression patterns as well as the built-in primitives. For example, how to match what appears to be a date ( 2014/10/18 )?
I want to know how to match things that might not easily be implemented with regular expression matching - for example, an URL ( http://google.com ).
Motivation:
In the Java world, Scanner is a special case, it is an extremely finicky class that teachers should not give new students instructions to use. In most cases the instructors do not even know how to use it correctly. It is hardly if ever used in professional production code so its value to students is extremely questionable.
Using Scanner implies all the other things this question and answer mentions. It is never just about Scanner it is about how to solve these common problems with Scanner that are always co morbid problems in almost all the question that get Scanner wrong. It is never just about next() vs nextLine(), that is just a symptom of the finickiness of the implementation of the class, there are always other issues in the code posting in questions asking about Scanner.
The answer shows a complete, idiomatic implementation of 99% of cases where Scanner is used and asked about on StackOverflow.
Especially in beginner code. If you think this answer is too complex then complain to the instructors that tell new students to use Scanner before explaining the intricacies, quirks, non-obvious side effects and peculiarities of its behavior.
Scanner is the a great teaching moment about how important the Principle of least astonishment is and why consistent behavior and semantics are important in naming methods and method arguments.
Note to students:
You will probably never actually see Scanner used in
professional/commercial line of business apps because everything it
does is done better by something else. Real world software has to be
more resilient and maintainable than Scanner allows you to write
code. Real world software uses standardized file format parsers and
documented file formats, not the adhoc input formats that you are
given in stand alone assignments.

Idiomatic Example:
The following is how to properly use the java.util.Scanner class to interactively read user input from System.in correctly( sometimes referred to as stdin, especially in C, C++ and other languages as well as in Unix and Linux). It idiomatically demonstrates the most common things that are requested to be done.
package com.stackoverflow.scanner;
import javax.annotation.Nonnull;
import java.math.BigInteger;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.*;
import java.util.regex.Pattern;
import static java.lang.String.format;
public class ScannerExample
{
private static final Set<String> EXIT_COMMANDS;
private static final Set<String> HELP_COMMANDS;
private static final Pattern DATE_PATTERN;
private static final String HELP_MESSAGE;
static
{
final SortedSet<String> ecmds = new TreeSet<String>(String.CASE_INSENSITIVE_ORDER);
ecmds.addAll(Arrays.asList("exit", "done", "quit", "end", "fino"));
EXIT_COMMANDS = Collections.unmodifiableSortedSet(ecmds);
final SortedSet<String> hcmds = new TreeSet<String>(String.CASE_INSENSITIVE_ORDER);
hcmds.addAll(Arrays.asList("help", "helpi", "?"));
HELP_COMMANDS = Collections.unmodifiableSet(hcmds);
DATE_PATTERN = Pattern.compile("\\d{4}([-\\/])\\d{2}\\1\\d{2}"); // http://regex101.com/r/xB8dR3/1
HELP_MESSAGE = format("Please enter some data or enter one of the following commands to exit %s", EXIT_COMMANDS);
}
/**
* Using exceptions to control execution flow is always bad.
* That is why this is encapsulated in a method, this is done this
* way specifically so as not to introduce any external libraries
* so that this is a completely self contained example.
* #param s possible url
* #return true if s represents a valid url, false otherwise
*/
private static boolean isValidURL(#Nonnull final String s)
{
try { new URL(s); return true; }
catch (final MalformedURLException e) { return false; }
}
private static void output(#Nonnull final String format, #Nonnull final Object... args)
{
System.out.println(format(format, args));
}
public static void main(final String[] args)
{
final Scanner sis = new Scanner(System.in);
output(HELP_MESSAGE);
while (sis.hasNext())
{
if (sis.hasNextInt())
{
final int next = sis.nextInt();
output("You entered an Integer = %d", next);
}
else if (sis.hasNextLong())
{
final long next = sis.nextLong();
output("You entered a Long = %d", next);
}
else if (sis.hasNextDouble())
{
final double next = sis.nextDouble();
output("You entered a Double = %f", next);
}
else if (sis.hasNext("\\d+"))
{
final BigInteger next = sis.nextBigInteger();
output("You entered a BigInteger = %s", next);
}
else if (sis.hasNextBoolean())
{
final boolean next = sis.nextBoolean();
output("You entered a Boolean representation = %s", next);
}
else if (sis.hasNext(DATE_PATTERN))
{
final String next = sis.next(DATE_PATTERN);
output("You entered a Date representation = %s", next);
}
else // unclassified
{
final String next = sis.next();
if (isValidURL(next))
{
output("You entered a valid URL = %s", next);
}
else
{
if (EXIT_COMMANDS.contains(next))
{
output("Exit command %s issued, exiting!", next);
break;
}
else if (HELP_COMMANDS.contains(next)) { output(HELP_MESSAGE); }
else { output("You entered an unclassified String = %s", next); }
}
}
}
/*
This will close the underlying InputStream, in this case System.in, and free those resources.
WARNING: You will not be able to read from System.in anymore after you call .close().
If you wanted to use System.in for something else, then don't close the Scanner.
*/
sis.close();
System.exit(0);
}
}
Notes:
This may look like a lot of code, but it illustrates the minimum
effort needed to use the Scanner class correctly and not have to
deal with subtle bugs and side effects that plague those new to
programming and this terribly implemented class called
java.util.Scanner. It tries to illustrate what idiomatic Java code
should look like and behave like.
Below are some of the things I was thinking about when I wrote this example:
JDK Version:
I purposely kept this example compatible with JDK 6. If some scenario really demands a feature of JDK 7/8 I or someone else will post a new answer with specifics about how to modify this for that version JDK.
The majority of questions about this class come from students and they usually have restrictions on what they can use to solve a problem so I restricted this as much as I could to show how to do the common things without any other dependencies. In the 22+ years I have been working with Java and consulting the majority of that time I have never encountered professional use of this class in the 10's of millions of lines source code I have seen.
Processing commands:
This shows exactly how to idiomatically read commands from the user interactively and dispatch those commands. The majority of questions about java.util.Scanner are of the how can I get my program to quit when I enter some specific input category. This shows that clearly.
Naive Dispatcher
The dispatch logic is intentionally naive so as to not complicate the solution for new readers. A dispatcher based on a Strategy Pattern or Chain Of Responsibility pattern would be more appropriate for real world problems that would be much more complex.
Error Handling
The code was deliberately structured as to require no Exception handling because there is no scenario where some data might not be correct.
.hasNext() and .hasNextXxx()
I rarely see anyone using the .hasNext() properly, by testing for the generic .hasNext() to control the event loop, and then using the if(.hasNextXxx()) idiom lets you decide how and what to proceed with your code without having to worry about asking for an int when none is available, thus no exception handling code.
.nextXXX() vs .nextLine()
This is something that breaks everyone's code. It is a finicky detail that should not have to be dealt with and has a very obfusated bug that is hard to reason about because of it breaks the Principal of Least Astonishment
The .nextXXX() methods do not consume the line ending. .nextLine() does.
That means that calling .nextLine() immediately after .nextXXX() will just return the line ending. You have to call it again to actually get the next line.
This is why many people advocate either use nothing but the .nextXXX() methods or only .nextLine() but not both at the same time so that this finicky behavior does not trip you up. Personally I think the type safe methods are much better than having to then test and parse and catch errors manually.
Immutablity:
Notice that there are no mutable variables used in the code, this is important to learn how to do, it eliminates four of the most major sources of runtime errors and subtle bugs.
No nulls means no possibility of a NullPointerExceptions!
No mutability means that you don't have to worry about method arguments changing or anything else changing. When you step debug through you never have to use watch to see what variables are change to what values, if they are changing. This makes the logic 100% deterministic when you read it.
No mutability means your code is automatically thread-safe.
No side effects. If nothing can change, the you don't have to worry about some subtle side effect of some edge case changing something unexpectedly!
Read this if you don't understand how to apply the final keyword in your own code.
Using a Set instead of massive switch or if/elseif blocks:
Notice how I use a Set<String> and use .contains() to classify the commands instead of a massive switch or if/elseif monstrosity that would bloat your code and more importantly make maintenance a nightmare! Adding a new overloaded command is as simple as adding a new String to the array in the constructor.
This also would work very well with i18n and i10n and the proper ResourceBundles.
A Map<Locale,Set<String>> would let you have multiple language support with very little overhead!
#Nonnull
I have decided that all my code should explicitly declare if something is #Nonnull or #Nullable. It lets your IDE help warn you about potential NullPointerException hazards and when you do not have to check.
Most importantly it documents the expectation for future readers that none of these method parameters should be null.
Calling .close()
Really think about this one before you do it.
What do you think will happen System.in if you were to call sis.close()? See the comments in the listing above.
Please fork and send pull requests and I will update this question and answer for other basic usage scenarios.

Related

Infinite recursive call [duplicate]

I am trying to implement a tail-recursive factorial calculator but I am still getting a stack overflow. Can anyone help me out in figuring out why?
I have read that Java 8 supports Tail call optimization, but I am thinking I must not be implementing it correctly.
I have read that it is possible using lambda expressions. I am not sure I fully understand this concept but I am still reading.
I am just looking for any advice on how to get this to use real tail call optimization, lambda expressions or however I can.
code:
package factorielRecursiveTerminale;
import java.math.BigInteger;
import java.util.Scanner;
public class factorielRecursiveTerminale {
public static BigInteger factoriel(BigInteger n, BigInteger m) {
if (n.compareTo(BigInteger.ZERO) < 1) return m;
return factoriel(n.subtract(BigInteger.ONE), n.multiply(m));
}
public static BigInteger fact(int n) { //convertir l'entree en BigInteger et lancer la recursion
if(n < 0) {
return BigInteger.valueOf(-1);
}
BigInteger b = BigInteger.valueOf(n);
return factoriel(b, BigInteger.ONE);
}
public static void runBigFact() { //gestion des erreurs + boucle d'entree de valeurs.
String valeurRecu = "";
int valeur;
BigInteger resultat;
System.out.println("Calcul Factoriel\n");
while(!valeurRecu.contentEquals("q")){
System.out.println("Entrer la valeur a calculer (q - quitter) : ");
Scanner entree = new Scanner(System.in);
valeurRecu = entree.nextLine();
if (valeurRecu.contentEquals("q")) entree.close();
else {
try {
valeur = Integer.parseInt(valeurRecu);
}catch (NumberFormatException e){
System.out.println("Pas un entier. Essayer encore.\n");
continue;
}
try {
resultat = fact(valeur);
if(resultat.compareTo(BigInteger.valueOf(-1)) == 0) {
System.out.println("Valeur negative. Essayer encore.\n");
}
else System.out.println("Factoriel " + valeur + " -> " + fact(valeur) + "\n");
} catch(StackOverflowError e) {
System.out.println("Depassement de la pile. Essayer un entier plus petit.\n");
continue;
}
}
}
System.out.println("Au revoir! :)\n");
}
public static void main(String[] args) {
runBigFact();
}
}
I have read that JAVA 8 supports Tail call optimization, but I am thinking I must not be implementing it correctly.
Then you have read wrong. Or, you've read a correct statement but didn't interpret it correctly.
Java, the language, does not support tail call recursion. It never has. It probably never will*.
However, java, the VM, has a few features that make it easier for other, non-java languages which nevertheless compile into class files to run on a java runtime, to support TCO. That's, presumably, what you read about.
I am just looking for any advice on how to get this to use real tail call optimization, lambda expressions or however I can.
Write it in scala or some such.
Seriously, how does java not have TCO???
TCO is pricey: Java has this rule that when errors occur you get a stack trace, and stack traces are a well defined concept that, crucially, tracks 1 stack frame for each logical call. This cannot continue if TCO exists. There are options, of course: Each individual frame on stack could gain a 'counter' so that the stack trace remains a smallish memory footprint while correctly representing 'and this sequence of calls has recurred 8190581 times'. It's also a boatload of text in the lang spec about how it works, when it does and doesn't kick in, and what it all means, and any additional pages in the spec are maintenance burdens forever - it's not a case of 'it is strictly superior to add TCO to java so when we get around to it, slam dunk, and any Pull Requests with the feature will be integrated immediately'.
Furthermore, TCO as a model is a way of doing things, but it's not the only way. For anything that could be written as a TCO-recursive application, it is generally not all that difficult to refactor that into a loop-based, non-recursing algorithm. Contrast to, say, yield-based async operations, where you can of course rewrite (hey, it's all turing machines), but the rewrite would be difficult, and the resulting code considerably harder to understand. I don't want to get into the value (or lack thereof) of yield/async style coding, just making the point that TCO does not have that veneer of 'ah, but, if TCO is a good idea, then only TCO will do'.
I don't have the links off-hand, but statements in this vein have been said by those who hold quite a bit of sway over the future of java, such as Brian Goetz, Mark Reinhold, etc. If you are really dedicated to try to see this added to java, I suggest you search the web for these statements and then try to shape some arguments specifically to address the concerns they state. Because if you can't convince those folks, it's never going to happen.
So what do I do in java?
Don't use recursion; use while or for instead.
UPDATE: What about that blog entry?
In comments you have linked to this blog entry. That's.. not TCO.
That's using lambdas to write a framework that lets you more or less emulate TCO, but it isn't TCO. The blog describes a little framework - and thus, you need all that stuff they pasted: The TailCall interface in particular.
That code works like this:
Your 'recursive' method isn't recursive at all, it always returns quickly without calling itself.
It returns a lambda which may call itself, though. But, as we just covered, calling yourself returns quickly without recursion, and it returns a function.
The framework will execute your function, which produces, usually, a function (or an actual result). It loops (so no recursion), repeatedly applying the process of: "Call the function. If it returns a function, then loop. If it returns a result, okay, that's the result we wanted so just return that".
That describes what TCO tries to accomplish (repeatedly invoke the same function over and over with different arguments until a hardcoded edge case is reached, and then reverse back out), but doesn't use TCO to do it.
Hence, that blog post saying 'look, TCO in java!' is misleading.
It's like me saying: "Look, paintbrushes on tunnels walls!" and describing how to use cans of spray paint to paint the tunnel wall in a way that looks like it was hand brushed. That is nice, but it's misleading to call it 'paintbrushing a wall'. At best you can say: "Looking to make paintbrush style art in tunnels? Well, you can't, and I can't fix that, but I can tell you how to get similar results!".
*) Never say never and all that, but I mean: There are no plans on the horizon, and the plans for the future of the java platform go many years into the future and are quite public. I'd take 1 to 40 odds on 'java (the language) does not have tail call recursion within 4 years' and still take that bet.
You may find this useful. I was able to get some improvement over your previous attempt but in this case it is not the size of the BigInteger object that causes the SO. On my machine, both of these methods result in a Stack Overflow between 14000 and 15000 for n. The simpleLong is just a basic recursive method to decrement the Long and it still blows up at 15000. Both succeed at 14000.
public static void main(String[] args) {
count = 0;
long n = 14000;
simpleLong(n);
factoriel(BigInteger.valueOf(n));
}
static BigInteger factoriel(BigInteger n) {
if (n.compareTo(BigInteger.TWO) == 1) {
return factoriel(n.subtract(BigInteger.ONE)).multiply(n);
}
return n;
}
static long simpleLong(long n) {
if (n > 1) {
simpleLong(n-1);
}
return n;
}

Compile error on SPOJ site [duplicate]

This is meant to be a canonical question/answer that can be used as a
duplicate target. These requirements are based on the most common
questions posted every day and may be added to as needed. They all
require the same basic code structure to get to each of the scenarios
and they are generally dependent on one another.
Scanner seems like a "simple" class to use, and that is where the first mistake is made. It is not simple, it has all kinds of non-obvious side effect and aberrant behaviors that break the Principle of Least Astonishment in very subtle ways.
So this might seem to be overkill for this class, but the peeling the onions errors and problems are all simple, but taken together they are very complex because of their interactions and side effects. This is why there are so many questions about it on Stack Overflow every day.
Common Scanner questions:
Most Scanner questions include failed attempts at more than one of these things.
I want to be able to have my program automatically wait for the next input after each previous input as well.
I want to know how to detect an exit command and end my program when that command is entered.
I want to know how to match multiple commands for the exit command in a case-insensitive way.
I want to be able to match regular expression patterns as well as the built-in primitives. For example, how to match what appears to be a date ( 2014/10/18 )?
I want to know how to match things that might not easily be implemented with regular expression matching - for example, an URL ( http://google.com ).
Motivation:
In the Java world, Scanner is a special case, it is an extremely finicky class that teachers should not give new students instructions to use. In most cases the instructors do not even know how to use it correctly. It is hardly if ever used in professional production code so its value to students is extremely questionable.
Using Scanner implies all the other things this question and answer mentions. It is never just about Scanner it is about how to solve these common problems with Scanner that are always co morbid problems in almost all the question that get Scanner wrong. It is never just about next() vs nextLine(), that is just a symptom of the finickiness of the implementation of the class, there are always other issues in the code posting in questions asking about Scanner.
The answer shows a complete, idiomatic implementation of 99% of cases where Scanner is used and asked about on StackOverflow.
Especially in beginner code. If you think this answer is too complex then complain to the instructors that tell new students to use Scanner before explaining the intricacies, quirks, non-obvious side effects and peculiarities of its behavior.
Scanner is the a great teaching moment about how important the Principle of least astonishment is and why consistent behavior and semantics are important in naming methods and method arguments.
Note to students:
You will probably never actually see Scanner used in
professional/commercial line of business apps because everything it
does is done better by something else. Real world software has to be
more resilient and maintainable than Scanner allows you to write
code. Real world software uses standardized file format parsers and
documented file formats, not the adhoc input formats that you are
given in stand alone assignments.
Idiomatic Example:
The following is how to properly use the java.util.Scanner class to interactively read user input from System.in correctly( sometimes referred to as stdin, especially in C, C++ and other languages as well as in Unix and Linux). It idiomatically demonstrates the most common things that are requested to be done.
package com.stackoverflow.scanner;
import javax.annotation.Nonnull;
import java.math.BigInteger;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.*;
import java.util.regex.Pattern;
import static java.lang.String.format;
public class ScannerExample
{
private static final Set<String> EXIT_COMMANDS;
private static final Set<String> HELP_COMMANDS;
private static final Pattern DATE_PATTERN;
private static final String HELP_MESSAGE;
static
{
final SortedSet<String> ecmds = new TreeSet<String>(String.CASE_INSENSITIVE_ORDER);
ecmds.addAll(Arrays.asList("exit", "done", "quit", "end", "fino"));
EXIT_COMMANDS = Collections.unmodifiableSortedSet(ecmds);
final SortedSet<String> hcmds = new TreeSet<String>(String.CASE_INSENSITIVE_ORDER);
hcmds.addAll(Arrays.asList("help", "helpi", "?"));
HELP_COMMANDS = Collections.unmodifiableSet(hcmds);
DATE_PATTERN = Pattern.compile("\\d{4}([-\\/])\\d{2}\\1\\d{2}"); // http://regex101.com/r/xB8dR3/1
HELP_MESSAGE = format("Please enter some data or enter one of the following commands to exit %s", EXIT_COMMANDS);
}
/**
* Using exceptions to control execution flow is always bad.
* That is why this is encapsulated in a method, this is done this
* way specifically so as not to introduce any external libraries
* so that this is a completely self contained example.
* #param s possible url
* #return true if s represents a valid url, false otherwise
*/
private static boolean isValidURL(#Nonnull final String s)
{
try { new URL(s); return true; }
catch (final MalformedURLException e) { return false; }
}
private static void output(#Nonnull final String format, #Nonnull final Object... args)
{
System.out.println(format(format, args));
}
public static void main(final String[] args)
{
final Scanner sis = new Scanner(System.in);
output(HELP_MESSAGE);
while (sis.hasNext())
{
if (sis.hasNextInt())
{
final int next = sis.nextInt();
output("You entered an Integer = %d", next);
}
else if (sis.hasNextLong())
{
final long next = sis.nextLong();
output("You entered a Long = %d", next);
}
else if (sis.hasNextDouble())
{
final double next = sis.nextDouble();
output("You entered a Double = %f", next);
}
else if (sis.hasNext("\\d+"))
{
final BigInteger next = sis.nextBigInteger();
output("You entered a BigInteger = %s", next);
}
else if (sis.hasNextBoolean())
{
final boolean next = sis.nextBoolean();
output("You entered a Boolean representation = %s", next);
}
else if (sis.hasNext(DATE_PATTERN))
{
final String next = sis.next(DATE_PATTERN);
output("You entered a Date representation = %s", next);
}
else // unclassified
{
final String next = sis.next();
if (isValidURL(next))
{
output("You entered a valid URL = %s", next);
}
else
{
if (EXIT_COMMANDS.contains(next))
{
output("Exit command %s issued, exiting!", next);
break;
}
else if (HELP_COMMANDS.contains(next)) { output(HELP_MESSAGE); }
else { output("You entered an unclassified String = %s", next); }
}
}
}
/*
This will close the underlying InputStream, in this case System.in, and free those resources.
WARNING: You will not be able to read from System.in anymore after you call .close().
If you wanted to use System.in for something else, then don't close the Scanner.
*/
sis.close();
System.exit(0);
}
}
Notes:
This may look like a lot of code, but it illustrates the minimum
effort needed to use the Scanner class correctly and not have to
deal with subtle bugs and side effects that plague those new to
programming and this terribly implemented class called
java.util.Scanner. It tries to illustrate what idiomatic Java code
should look like and behave like.
Below are some of the things I was thinking about when I wrote this example:
JDK Version:
I purposely kept this example compatible with JDK 6. If some scenario really demands a feature of JDK 7/8 I or someone else will post a new answer with specifics about how to modify this for that version JDK.
The majority of questions about this class come from students and they usually have restrictions on what they can use to solve a problem so I restricted this as much as I could to show how to do the common things without any other dependencies. In the 22+ years I have been working with Java and consulting the majority of that time I have never encountered professional use of this class in the 10's of millions of lines source code I have seen.
Processing commands:
This shows exactly how to idiomatically read commands from the user interactively and dispatch those commands. The majority of questions about java.util.Scanner are of the how can I get my program to quit when I enter some specific input category. This shows that clearly.
Naive Dispatcher
The dispatch logic is intentionally naive so as to not complicate the solution for new readers. A dispatcher based on a Strategy Pattern or Chain Of Responsibility pattern would be more appropriate for real world problems that would be much more complex.
Error Handling
The code was deliberately structured as to require no Exception handling because there is no scenario where some data might not be correct.
.hasNext() and .hasNextXxx()
I rarely see anyone using the .hasNext() properly, by testing for the generic .hasNext() to control the event loop, and then using the if(.hasNextXxx()) idiom lets you decide how and what to proceed with your code without having to worry about asking for an int when none is available, thus no exception handling code.
.nextXXX() vs .nextLine()
This is something that breaks everyone's code. It is a finicky detail that should not have to be dealt with and has a very obfusated bug that is hard to reason about because of it breaks the Principal of Least Astonishment
The .nextXXX() methods do not consume the line ending. .nextLine() does.
That means that calling .nextLine() immediately after .nextXXX() will just return the line ending. You have to call it again to actually get the next line.
This is why many people advocate either use nothing but the .nextXXX() methods or only .nextLine() but not both at the same time so that this finicky behavior does not trip you up. Personally I think the type safe methods are much better than having to then test and parse and catch errors manually.
Immutablity:
Notice that there are no mutable variables used in the code, this is important to learn how to do, it eliminates four of the most major sources of runtime errors and subtle bugs.
No nulls means no possibility of a NullPointerExceptions!
No mutability means that you don't have to worry about method arguments changing or anything else changing. When you step debug through you never have to use watch to see what variables are change to what values, if they are changing. This makes the logic 100% deterministic when you read it.
No mutability means your code is automatically thread-safe.
No side effects. If nothing can change, the you don't have to worry about some subtle side effect of some edge case changing something unexpectedly!
Read this if you don't understand how to apply the final keyword in your own code.
Using a Set instead of massive switch or if/elseif blocks:
Notice how I use a Set<String> and use .contains() to classify the commands instead of a massive switch or if/elseif monstrosity that would bloat your code and more importantly make maintenance a nightmare! Adding a new overloaded command is as simple as adding a new String to the array in the constructor.
This also would work very well with i18n and i10n and the proper ResourceBundles.
A Map<Locale,Set<String>> would let you have multiple language support with very little overhead!
#Nonnull
I have decided that all my code should explicitly declare if something is #Nonnull or #Nullable. It lets your IDE help warn you about potential NullPointerException hazards and when you do not have to check.
Most importantly it documents the expectation for future readers that none of these method parameters should be null.
Calling .close()
Really think about this one before you do it.
What do you think will happen System.in if you were to call sis.close()? See the comments in the listing above.
Please fork and send pull requests and I will update this question and answer for other basic usage scenarios.

On closing Scanner in multiple java classes the main class depicts error [duplicate]

This is meant to be a canonical question/answer that can be used as a
duplicate target. These requirements are based on the most common
questions posted every day and may be added to as needed. They all
require the same basic code structure to get to each of the scenarios
and they are generally dependent on one another.
Scanner seems like a "simple" class to use, and that is where the first mistake is made. It is not simple, it has all kinds of non-obvious side effect and aberrant behaviors that break the Principle of Least Astonishment in very subtle ways.
So this might seem to be overkill for this class, but the peeling the onions errors and problems are all simple, but taken together they are very complex because of their interactions and side effects. This is why there are so many questions about it on Stack Overflow every day.
Common Scanner questions:
Most Scanner questions include failed attempts at more than one of these things.
I want to be able to have my program automatically wait for the next input after each previous input as well.
I want to know how to detect an exit command and end my program when that command is entered.
I want to know how to match multiple commands for the exit command in a case-insensitive way.
I want to be able to match regular expression patterns as well as the built-in primitives. For example, how to match what appears to be a date ( 2014/10/18 )?
I want to know how to match things that might not easily be implemented with regular expression matching - for example, an URL ( http://google.com ).
Motivation:
In the Java world, Scanner is a special case, it is an extremely finicky class that teachers should not give new students instructions to use. In most cases the instructors do not even know how to use it correctly. It is hardly if ever used in professional production code so its value to students is extremely questionable.
Using Scanner implies all the other things this question and answer mentions. It is never just about Scanner it is about how to solve these common problems with Scanner that are always co morbid problems in almost all the question that get Scanner wrong. It is never just about next() vs nextLine(), that is just a symptom of the finickiness of the implementation of the class, there are always other issues in the code posting in questions asking about Scanner.
The answer shows a complete, idiomatic implementation of 99% of cases where Scanner is used and asked about on StackOverflow.
Especially in beginner code. If you think this answer is too complex then complain to the instructors that tell new students to use Scanner before explaining the intricacies, quirks, non-obvious side effects and peculiarities of its behavior.
Scanner is the a great teaching moment about how important the Principle of least astonishment is and why consistent behavior and semantics are important in naming methods and method arguments.
Note to students:
You will probably never actually see Scanner used in
professional/commercial line of business apps because everything it
does is done better by something else. Real world software has to be
more resilient and maintainable than Scanner allows you to write
code. Real world software uses standardized file format parsers and
documented file formats, not the adhoc input formats that you are
given in stand alone assignments.
Idiomatic Example:
The following is how to properly use the java.util.Scanner class to interactively read user input from System.in correctly( sometimes referred to as stdin, especially in C, C++ and other languages as well as in Unix and Linux). It idiomatically demonstrates the most common things that are requested to be done.
package com.stackoverflow.scanner;
import javax.annotation.Nonnull;
import java.math.BigInteger;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.*;
import java.util.regex.Pattern;
import static java.lang.String.format;
public class ScannerExample
{
private static final Set<String> EXIT_COMMANDS;
private static final Set<String> HELP_COMMANDS;
private static final Pattern DATE_PATTERN;
private static final String HELP_MESSAGE;
static
{
final SortedSet<String> ecmds = new TreeSet<String>(String.CASE_INSENSITIVE_ORDER);
ecmds.addAll(Arrays.asList("exit", "done", "quit", "end", "fino"));
EXIT_COMMANDS = Collections.unmodifiableSortedSet(ecmds);
final SortedSet<String> hcmds = new TreeSet<String>(String.CASE_INSENSITIVE_ORDER);
hcmds.addAll(Arrays.asList("help", "helpi", "?"));
HELP_COMMANDS = Collections.unmodifiableSet(hcmds);
DATE_PATTERN = Pattern.compile("\\d{4}([-\\/])\\d{2}\\1\\d{2}"); // http://regex101.com/r/xB8dR3/1
HELP_MESSAGE = format("Please enter some data or enter one of the following commands to exit %s", EXIT_COMMANDS);
}
/**
* Using exceptions to control execution flow is always bad.
* That is why this is encapsulated in a method, this is done this
* way specifically so as not to introduce any external libraries
* so that this is a completely self contained example.
* #param s possible url
* #return true if s represents a valid url, false otherwise
*/
private static boolean isValidURL(#Nonnull final String s)
{
try { new URL(s); return true; }
catch (final MalformedURLException e) { return false; }
}
private static void output(#Nonnull final String format, #Nonnull final Object... args)
{
System.out.println(format(format, args));
}
public static void main(final String[] args)
{
final Scanner sis = new Scanner(System.in);
output(HELP_MESSAGE);
while (sis.hasNext())
{
if (sis.hasNextInt())
{
final int next = sis.nextInt();
output("You entered an Integer = %d", next);
}
else if (sis.hasNextLong())
{
final long next = sis.nextLong();
output("You entered a Long = %d", next);
}
else if (sis.hasNextDouble())
{
final double next = sis.nextDouble();
output("You entered a Double = %f", next);
}
else if (sis.hasNext("\\d+"))
{
final BigInteger next = sis.nextBigInteger();
output("You entered a BigInteger = %s", next);
}
else if (sis.hasNextBoolean())
{
final boolean next = sis.nextBoolean();
output("You entered a Boolean representation = %s", next);
}
else if (sis.hasNext(DATE_PATTERN))
{
final String next = sis.next(DATE_PATTERN);
output("You entered a Date representation = %s", next);
}
else // unclassified
{
final String next = sis.next();
if (isValidURL(next))
{
output("You entered a valid URL = %s", next);
}
else
{
if (EXIT_COMMANDS.contains(next))
{
output("Exit command %s issued, exiting!", next);
break;
}
else if (HELP_COMMANDS.contains(next)) { output(HELP_MESSAGE); }
else { output("You entered an unclassified String = %s", next); }
}
}
}
/*
This will close the underlying InputStream, in this case System.in, and free those resources.
WARNING: You will not be able to read from System.in anymore after you call .close().
If you wanted to use System.in for something else, then don't close the Scanner.
*/
sis.close();
System.exit(0);
}
}
Notes:
This may look like a lot of code, but it illustrates the minimum
effort needed to use the Scanner class correctly and not have to
deal with subtle bugs and side effects that plague those new to
programming and this terribly implemented class called
java.util.Scanner. It tries to illustrate what idiomatic Java code
should look like and behave like.
Below are some of the things I was thinking about when I wrote this example:
JDK Version:
I purposely kept this example compatible with JDK 6. If some scenario really demands a feature of JDK 7/8 I or someone else will post a new answer with specifics about how to modify this for that version JDK.
The majority of questions about this class come from students and they usually have restrictions on what they can use to solve a problem so I restricted this as much as I could to show how to do the common things without any other dependencies. In the 22+ years I have been working with Java and consulting the majority of that time I have never encountered professional use of this class in the 10's of millions of lines source code I have seen.
Processing commands:
This shows exactly how to idiomatically read commands from the user interactively and dispatch those commands. The majority of questions about java.util.Scanner are of the how can I get my program to quit when I enter some specific input category. This shows that clearly.
Naive Dispatcher
The dispatch logic is intentionally naive so as to not complicate the solution for new readers. A dispatcher based on a Strategy Pattern or Chain Of Responsibility pattern would be more appropriate for real world problems that would be much more complex.
Error Handling
The code was deliberately structured as to require no Exception handling because there is no scenario where some data might not be correct.
.hasNext() and .hasNextXxx()
I rarely see anyone using the .hasNext() properly, by testing for the generic .hasNext() to control the event loop, and then using the if(.hasNextXxx()) idiom lets you decide how and what to proceed with your code without having to worry about asking for an int when none is available, thus no exception handling code.
.nextXXX() vs .nextLine()
This is something that breaks everyone's code. It is a finicky detail that should not have to be dealt with and has a very obfusated bug that is hard to reason about because of it breaks the Principal of Least Astonishment
The .nextXXX() methods do not consume the line ending. .nextLine() does.
That means that calling .nextLine() immediately after .nextXXX() will just return the line ending. You have to call it again to actually get the next line.
This is why many people advocate either use nothing but the .nextXXX() methods or only .nextLine() but not both at the same time so that this finicky behavior does not trip you up. Personally I think the type safe methods are much better than having to then test and parse and catch errors manually.
Immutablity:
Notice that there are no mutable variables used in the code, this is important to learn how to do, it eliminates four of the most major sources of runtime errors and subtle bugs.
No nulls means no possibility of a NullPointerExceptions!
No mutability means that you don't have to worry about method arguments changing or anything else changing. When you step debug through you never have to use watch to see what variables are change to what values, if they are changing. This makes the logic 100% deterministic when you read it.
No mutability means your code is automatically thread-safe.
No side effects. If nothing can change, the you don't have to worry about some subtle side effect of some edge case changing something unexpectedly!
Read this if you don't understand how to apply the final keyword in your own code.
Using a Set instead of massive switch or if/elseif blocks:
Notice how I use a Set<String> and use .contains() to classify the commands instead of a massive switch or if/elseif monstrosity that would bloat your code and more importantly make maintenance a nightmare! Adding a new overloaded command is as simple as adding a new String to the array in the constructor.
This also would work very well with i18n and i10n and the proper ResourceBundles.
A Map<Locale,Set<String>> would let you have multiple language support with very little overhead!
#Nonnull
I have decided that all my code should explicitly declare if something is #Nonnull or #Nullable. It lets your IDE help warn you about potential NullPointerException hazards and when you do not have to check.
Most importantly it documents the expectation for future readers that none of these method parameters should be null.
Calling .close()
Really think about this one before you do it.
What do you think will happen System.in if you were to call sis.close()? See the comments in the listing above.
Please fork and send pull requests and I will update this question and answer for other basic usage scenarios.

Feed java program scanner(system.in) instructions with text files [duplicate]

This is meant to be a canonical question/answer that can be used as a
duplicate target. These requirements are based on the most common
questions posted every day and may be added to as needed. They all
require the same basic code structure to get to each of the scenarios
and they are generally dependent on one another.
Scanner seems like a "simple" class to use, and that is where the first mistake is made. It is not simple, it has all kinds of non-obvious side effect and aberrant behaviors that break the Principle of Least Astonishment in very subtle ways.
So this might seem to be overkill for this class, but the peeling the onions errors and problems are all simple, but taken together they are very complex because of their interactions and side effects. This is why there are so many questions about it on Stack Overflow every day.
Common Scanner questions:
Most Scanner questions include failed attempts at more than one of these things.
I want to be able to have my program automatically wait for the next input after each previous input as well.
I want to know how to detect an exit command and end my program when that command is entered.
I want to know how to match multiple commands for the exit command in a case-insensitive way.
I want to be able to match regular expression patterns as well as the built-in primitives. For example, how to match what appears to be a date ( 2014/10/18 )?
I want to know how to match things that might not easily be implemented with regular expression matching - for example, an URL ( http://google.com ).
Motivation:
In the Java world, Scanner is a special case, it is an extremely finicky class that teachers should not give new students instructions to use. In most cases the instructors do not even know how to use it correctly. It is hardly if ever used in professional production code so its value to students is extremely questionable.
Using Scanner implies all the other things this question and answer mentions. It is never just about Scanner it is about how to solve these common problems with Scanner that are always co morbid problems in almost all the question that get Scanner wrong. It is never just about next() vs nextLine(), that is just a symptom of the finickiness of the implementation of the class, there are always other issues in the code posting in questions asking about Scanner.
The answer shows a complete, idiomatic implementation of 99% of cases where Scanner is used and asked about on StackOverflow.
Especially in beginner code. If you think this answer is too complex then complain to the instructors that tell new students to use Scanner before explaining the intricacies, quirks, non-obvious side effects and peculiarities of its behavior.
Scanner is the a great teaching moment about how important the Principle of least astonishment is and why consistent behavior and semantics are important in naming methods and method arguments.
Note to students:
You will probably never actually see Scanner used in
professional/commercial line of business apps because everything it
does is done better by something else. Real world software has to be
more resilient and maintainable than Scanner allows you to write
code. Real world software uses standardized file format parsers and
documented file formats, not the adhoc input formats that you are
given in stand alone assignments.
Idiomatic Example:
The following is how to properly use the java.util.Scanner class to interactively read user input from System.in correctly( sometimes referred to as stdin, especially in C, C++ and other languages as well as in Unix and Linux). It idiomatically demonstrates the most common things that are requested to be done.
package com.stackoverflow.scanner;
import javax.annotation.Nonnull;
import java.math.BigInteger;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.*;
import java.util.regex.Pattern;
import static java.lang.String.format;
public class ScannerExample
{
private static final Set<String> EXIT_COMMANDS;
private static final Set<String> HELP_COMMANDS;
private static final Pattern DATE_PATTERN;
private static final String HELP_MESSAGE;
static
{
final SortedSet<String> ecmds = new TreeSet<String>(String.CASE_INSENSITIVE_ORDER);
ecmds.addAll(Arrays.asList("exit", "done", "quit", "end", "fino"));
EXIT_COMMANDS = Collections.unmodifiableSortedSet(ecmds);
final SortedSet<String> hcmds = new TreeSet<String>(String.CASE_INSENSITIVE_ORDER);
hcmds.addAll(Arrays.asList("help", "helpi", "?"));
HELP_COMMANDS = Collections.unmodifiableSet(hcmds);
DATE_PATTERN = Pattern.compile("\\d{4}([-\\/])\\d{2}\\1\\d{2}"); // http://regex101.com/r/xB8dR3/1
HELP_MESSAGE = format("Please enter some data or enter one of the following commands to exit %s", EXIT_COMMANDS);
}
/**
* Using exceptions to control execution flow is always bad.
* That is why this is encapsulated in a method, this is done this
* way specifically so as not to introduce any external libraries
* so that this is a completely self contained example.
* #param s possible url
* #return true if s represents a valid url, false otherwise
*/
private static boolean isValidURL(#Nonnull final String s)
{
try { new URL(s); return true; }
catch (final MalformedURLException e) { return false; }
}
private static void output(#Nonnull final String format, #Nonnull final Object... args)
{
System.out.println(format(format, args));
}
public static void main(final String[] args)
{
final Scanner sis = new Scanner(System.in);
output(HELP_MESSAGE);
while (sis.hasNext())
{
if (sis.hasNextInt())
{
final int next = sis.nextInt();
output("You entered an Integer = %d", next);
}
else if (sis.hasNextLong())
{
final long next = sis.nextLong();
output("You entered a Long = %d", next);
}
else if (sis.hasNextDouble())
{
final double next = sis.nextDouble();
output("You entered a Double = %f", next);
}
else if (sis.hasNext("\\d+"))
{
final BigInteger next = sis.nextBigInteger();
output("You entered a BigInteger = %s", next);
}
else if (sis.hasNextBoolean())
{
final boolean next = sis.nextBoolean();
output("You entered a Boolean representation = %s", next);
}
else if (sis.hasNext(DATE_PATTERN))
{
final String next = sis.next(DATE_PATTERN);
output("You entered a Date representation = %s", next);
}
else // unclassified
{
final String next = sis.next();
if (isValidURL(next))
{
output("You entered a valid URL = %s", next);
}
else
{
if (EXIT_COMMANDS.contains(next))
{
output("Exit command %s issued, exiting!", next);
break;
}
else if (HELP_COMMANDS.contains(next)) { output(HELP_MESSAGE); }
else { output("You entered an unclassified String = %s", next); }
}
}
}
/*
This will close the underlying InputStream, in this case System.in, and free those resources.
WARNING: You will not be able to read from System.in anymore after you call .close().
If you wanted to use System.in for something else, then don't close the Scanner.
*/
sis.close();
System.exit(0);
}
}
Notes:
This may look like a lot of code, but it illustrates the minimum
effort needed to use the Scanner class correctly and not have to
deal with subtle bugs and side effects that plague those new to
programming and this terribly implemented class called
java.util.Scanner. It tries to illustrate what idiomatic Java code
should look like and behave like.
Below are some of the things I was thinking about when I wrote this example:
JDK Version:
I purposely kept this example compatible with JDK 6. If some scenario really demands a feature of JDK 7/8 I or someone else will post a new answer with specifics about how to modify this for that version JDK.
The majority of questions about this class come from students and they usually have restrictions on what they can use to solve a problem so I restricted this as much as I could to show how to do the common things without any other dependencies. In the 22+ years I have been working with Java and consulting the majority of that time I have never encountered professional use of this class in the 10's of millions of lines source code I have seen.
Processing commands:
This shows exactly how to idiomatically read commands from the user interactively and dispatch those commands. The majority of questions about java.util.Scanner are of the how can I get my program to quit when I enter some specific input category. This shows that clearly.
Naive Dispatcher
The dispatch logic is intentionally naive so as to not complicate the solution for new readers. A dispatcher based on a Strategy Pattern or Chain Of Responsibility pattern would be more appropriate for real world problems that would be much more complex.
Error Handling
The code was deliberately structured as to require no Exception handling because there is no scenario where some data might not be correct.
.hasNext() and .hasNextXxx()
I rarely see anyone using the .hasNext() properly, by testing for the generic .hasNext() to control the event loop, and then using the if(.hasNextXxx()) idiom lets you decide how and what to proceed with your code without having to worry about asking for an int when none is available, thus no exception handling code.
.nextXXX() vs .nextLine()
This is something that breaks everyone's code. It is a finicky detail that should not have to be dealt with and has a very obfusated bug that is hard to reason about because of it breaks the Principal of Least Astonishment
The .nextXXX() methods do not consume the line ending. .nextLine() does.
That means that calling .nextLine() immediately after .nextXXX() will just return the line ending. You have to call it again to actually get the next line.
This is why many people advocate either use nothing but the .nextXXX() methods or only .nextLine() but not both at the same time so that this finicky behavior does not trip you up. Personally I think the type safe methods are much better than having to then test and parse and catch errors manually.
Immutablity:
Notice that there are no mutable variables used in the code, this is important to learn how to do, it eliminates four of the most major sources of runtime errors and subtle bugs.
No nulls means no possibility of a NullPointerExceptions!
No mutability means that you don't have to worry about method arguments changing or anything else changing. When you step debug through you never have to use watch to see what variables are change to what values, if they are changing. This makes the logic 100% deterministic when you read it.
No mutability means your code is automatically thread-safe.
No side effects. If nothing can change, the you don't have to worry about some subtle side effect of some edge case changing something unexpectedly!
Read this if you don't understand how to apply the final keyword in your own code.
Using a Set instead of massive switch or if/elseif blocks:
Notice how I use a Set<String> and use .contains() to classify the commands instead of a massive switch or if/elseif monstrosity that would bloat your code and more importantly make maintenance a nightmare! Adding a new overloaded command is as simple as adding a new String to the array in the constructor.
This also would work very well with i18n and i10n and the proper ResourceBundles.
A Map<Locale,Set<String>> would let you have multiple language support with very little overhead!
#Nonnull
I have decided that all my code should explicitly declare if something is #Nonnull or #Nullable. It lets your IDE help warn you about potential NullPointerException hazards and when you do not have to check.
Most importantly it documents the expectation for future readers that none of these method parameters should be null.
Calling .close()
Really think about this one before you do it.
What do you think will happen System.in if you were to call sis.close()? See the comments in the listing above.
Please fork and send pull requests and I will update this question and answer for other basic usage scenarios.

How to use java.util.Scanner to correctly read user input from System.in and act on it?

This is meant to be a canonical question/answer that can be used as a
duplicate target. These requirements are based on the most common
questions posted every day and may be added to as needed. They all
require the same basic code structure to get to each of the scenarios
and they are generally dependent on one another.
Scanner seems like a "simple" class to use, and that is where the first mistake is made. It is not simple, it has all kinds of non-obvious side effect and aberrant behaviors that break the Principle of Least Astonishment in very subtle ways.
So this might seem to be overkill for this class, but the peeling the onions errors and problems are all simple, but taken together they are very complex because of their interactions and side effects. This is why there are so many questions about it on Stack Overflow every day.
Common Scanner questions:
Most Scanner questions include failed attempts at more than one of these things.
I want to be able to have my program automatically wait for the next input after each previous input as well.
I want to know how to detect an exit command and end my program when that command is entered.
I want to know how to match multiple commands for the exit command in a case-insensitive way.
I want to be able to match regular expression patterns as well as the built-in primitives. For example, how to match what appears to be a date ( 2014/10/18 )?
I want to know how to match things that might not easily be implemented with regular expression matching - for example, an URL ( http://google.com ).
Motivation:
In the Java world, Scanner is a special case, it is an extremely finicky class that teachers should not give new students instructions to use. In most cases the instructors do not even know how to use it correctly. It is hardly if ever used in professional production code so its value to students is extremely questionable.
Using Scanner implies all the other things this question and answer mentions. It is never just about Scanner it is about how to solve these common problems with Scanner that are always co morbid problems in almost all the question that get Scanner wrong. It is never just about next() vs nextLine(), that is just a symptom of the finickiness of the implementation of the class, there are always other issues in the code posting in questions asking about Scanner.
The answer shows a complete, idiomatic implementation of 99% of cases where Scanner is used and asked about on StackOverflow.
Especially in beginner code. If you think this answer is too complex then complain to the instructors that tell new students to use Scanner before explaining the intricacies, quirks, non-obvious side effects and peculiarities of its behavior.
Scanner is the a great teaching moment about how important the Principle of least astonishment is and why consistent behavior and semantics are important in naming methods and method arguments.
Note to students:
You will probably never actually see Scanner used in
professional/commercial line of business apps because everything it
does is done better by something else. Real world software has to be
more resilient and maintainable than Scanner allows you to write
code. Real world software uses standardized file format parsers and
documented file formats, not the adhoc input formats that you are
given in stand alone assignments.
Idiomatic Example:
The following is how to properly use the java.util.Scanner class to interactively read user input from System.in correctly( sometimes referred to as stdin, especially in C, C++ and other languages as well as in Unix and Linux). It idiomatically demonstrates the most common things that are requested to be done.
package com.stackoverflow.scanner;
import javax.annotation.Nonnull;
import java.math.BigInteger;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.*;
import java.util.regex.Pattern;
import static java.lang.String.format;
public class ScannerExample
{
private static final Set<String> EXIT_COMMANDS;
private static final Set<String> HELP_COMMANDS;
private static final Pattern DATE_PATTERN;
private static final String HELP_MESSAGE;
static
{
final SortedSet<String> ecmds = new TreeSet<String>(String.CASE_INSENSITIVE_ORDER);
ecmds.addAll(Arrays.asList("exit", "done", "quit", "end", "fino"));
EXIT_COMMANDS = Collections.unmodifiableSortedSet(ecmds);
final SortedSet<String> hcmds = new TreeSet<String>(String.CASE_INSENSITIVE_ORDER);
hcmds.addAll(Arrays.asList("help", "helpi", "?"));
HELP_COMMANDS = Collections.unmodifiableSet(hcmds);
DATE_PATTERN = Pattern.compile("\\d{4}([-\\/])\\d{2}\\1\\d{2}"); // http://regex101.com/r/xB8dR3/1
HELP_MESSAGE = format("Please enter some data or enter one of the following commands to exit %s", EXIT_COMMANDS);
}
/**
* Using exceptions to control execution flow is always bad.
* That is why this is encapsulated in a method, this is done this
* way specifically so as not to introduce any external libraries
* so that this is a completely self contained example.
* #param s possible url
* #return true if s represents a valid url, false otherwise
*/
private static boolean isValidURL(#Nonnull final String s)
{
try { new URL(s); return true; }
catch (final MalformedURLException e) { return false; }
}
private static void output(#Nonnull final String format, #Nonnull final Object... args)
{
System.out.println(format(format, args));
}
public static void main(final String[] args)
{
final Scanner sis = new Scanner(System.in);
output(HELP_MESSAGE);
while (sis.hasNext())
{
if (sis.hasNextInt())
{
final int next = sis.nextInt();
output("You entered an Integer = %d", next);
}
else if (sis.hasNextLong())
{
final long next = sis.nextLong();
output("You entered a Long = %d", next);
}
else if (sis.hasNextDouble())
{
final double next = sis.nextDouble();
output("You entered a Double = %f", next);
}
else if (sis.hasNext("\\d+"))
{
final BigInteger next = sis.nextBigInteger();
output("You entered a BigInteger = %s", next);
}
else if (sis.hasNextBoolean())
{
final boolean next = sis.nextBoolean();
output("You entered a Boolean representation = %s", next);
}
else if (sis.hasNext(DATE_PATTERN))
{
final String next = sis.next(DATE_PATTERN);
output("You entered a Date representation = %s", next);
}
else // unclassified
{
final String next = sis.next();
if (isValidURL(next))
{
output("You entered a valid URL = %s", next);
}
else
{
if (EXIT_COMMANDS.contains(next))
{
output("Exit command %s issued, exiting!", next);
break;
}
else if (HELP_COMMANDS.contains(next)) { output(HELP_MESSAGE); }
else { output("You entered an unclassified String = %s", next); }
}
}
}
/*
This will close the underlying InputStream, in this case System.in, and free those resources.
WARNING: You will not be able to read from System.in anymore after you call .close().
If you wanted to use System.in for something else, then don't close the Scanner.
*/
sis.close();
System.exit(0);
}
}
Notes:
This may look like a lot of code, but it illustrates the minimum
effort needed to use the Scanner class correctly and not have to
deal with subtle bugs and side effects that plague those new to
programming and this terribly implemented class called
java.util.Scanner. It tries to illustrate what idiomatic Java code
should look like and behave like.
Below are some of the things I was thinking about when I wrote this example:
JDK Version:
I purposely kept this example compatible with JDK 6. If some scenario really demands a feature of JDK 7/8 I or someone else will post a new answer with specifics about how to modify this for that version JDK.
The majority of questions about this class come from students and they usually have restrictions on what they can use to solve a problem so I restricted this as much as I could to show how to do the common things without any other dependencies. In the 22+ years I have been working with Java and consulting the majority of that time I have never encountered professional use of this class in the 10's of millions of lines source code I have seen.
Processing commands:
This shows exactly how to idiomatically read commands from the user interactively and dispatch those commands. The majority of questions about java.util.Scanner are of the how can I get my program to quit when I enter some specific input category. This shows that clearly.
Naive Dispatcher
The dispatch logic is intentionally naive so as to not complicate the solution for new readers. A dispatcher based on a Strategy Pattern or Chain Of Responsibility pattern would be more appropriate for real world problems that would be much more complex.
Error Handling
The code was deliberately structured as to require no Exception handling because there is no scenario where some data might not be correct.
.hasNext() and .hasNextXxx()
I rarely see anyone using the .hasNext() properly, by testing for the generic .hasNext() to control the event loop, and then using the if(.hasNextXxx()) idiom lets you decide how and what to proceed with your code without having to worry about asking for an int when none is available, thus no exception handling code.
.nextXXX() vs .nextLine()
This is something that breaks everyone's code. It is a finicky detail that should not have to be dealt with and has a very obfusated bug that is hard to reason about because of it breaks the Principal of Least Astonishment
The .nextXXX() methods do not consume the line ending. .nextLine() does.
That means that calling .nextLine() immediately after .nextXXX() will just return the line ending. You have to call it again to actually get the next line.
This is why many people advocate either use nothing but the .nextXXX() methods or only .nextLine() but not both at the same time so that this finicky behavior does not trip you up. Personally I think the type safe methods are much better than having to then test and parse and catch errors manually.
Immutablity:
Notice that there are no mutable variables used in the code, this is important to learn how to do, it eliminates four of the most major sources of runtime errors and subtle bugs.
No nulls means no possibility of a NullPointerExceptions!
No mutability means that you don't have to worry about method arguments changing or anything else changing. When you step debug through you never have to use watch to see what variables are change to what values, if they are changing. This makes the logic 100% deterministic when you read it.
No mutability means your code is automatically thread-safe.
No side effects. If nothing can change, the you don't have to worry about some subtle side effect of some edge case changing something unexpectedly!
Read this if you don't understand how to apply the final keyword in your own code.
Using a Set instead of massive switch or if/elseif blocks:
Notice how I use a Set<String> and use .contains() to classify the commands instead of a massive switch or if/elseif monstrosity that would bloat your code and more importantly make maintenance a nightmare! Adding a new overloaded command is as simple as adding a new String to the array in the constructor.
This also would work very well with i18n and i10n and the proper ResourceBundles.
A Map<Locale,Set<String>> would let you have multiple language support with very little overhead!
#Nonnull
I have decided that all my code should explicitly declare if something is #Nonnull or #Nullable. It lets your IDE help warn you about potential NullPointerException hazards and when you do not have to check.
Most importantly it documents the expectation for future readers that none of these method parameters should be null.
Calling .close()
Really think about this one before you do it.
What do you think will happen System.in if you were to call sis.close()? See the comments in the listing above.
Please fork and send pull requests and I will update this question and answer for other basic usage scenarios.

Categories

Resources