Comparison problems [.equals()] in java - java

I am trying to determine whether a string contains a positive int or not. My code is:
public void isInt(String str) throws NotIntException{
String integer=str.replaceAll("\\d","");
System.out.println(integer);
if (!integer.equals("")){
throw new NotIntException("Wrong data type-check fields where an integer"+
" should be.");
}//end if
if (integer.equals("-")){
System.out.println(integer);
throw new NotIntException("Error-Can't have a negative count.");
}//end if
}//end method
I am testing this with a string "-1", which should, after the replaceAll(), become "-". This should enter both if-statements. But it only enters the first. I tried it with the == comparison too, just in case, but it didn't work either. What's odd to me is that whether I look to fulfill the second if-statement's condition or to fulfill its negation [i.e., !integer.equals("-")], the program still doesn't enter the if....
Thanks, usually my comparison issues are just me missing something basic, but I really don't see anything here...

Since you are throwing an Exception in your first if, so, your 2nd if will not even be tested.
if (!integer.equals("")){
throw new NotIntException("Wrong data type-check fields where an integer"+
" should be.");
}
if (integer.equals("-")){
System.out.println(integer);
throw new NotIntException("Error-Can't have a negative count.");
}
If your code enters the first if, it will not execute further.
But, why are you using this approach for your problem.
You can easily use Integer.parseInt to check for valid integer. And then if it is valid, then test whether its less than 0. It would be far easier and readable.

My solution:
public static boolean isPositiveInt(String str) {
try {
int number = Integer.parseInt(str.trim());
return number >= 0;
} catch (NumberFormatException e) {
return false;
}
}

If you want to simply read an int from a String, use Integer.parseInt(), although that would only work if you want to see if a string "is" an int, not contains one.
You could use a combination of Integer.parseInt() and a loop strategy to see if it contains an int fairly easily though, then just check if that is positive or not.

You approach is too complicated. I would keep it simple:
if (integer.startsWith("-")) {
// it's a negative number
}
if (!integer.matches("^\\d+$")) {
// it's not all-numbers
}
and forget the call to replaceAll()

Related

Scanner returns wrong int value

Java newbie here.
I made a function to simply return an int given by user through Scanner.
The goal is to avoid an error if the user does not type an integer, notify them and let them retry.
It works fine if the value is an integer on the first try, but if I type a char (get an error, function "restart") then the function will return the "default" zero.
Tried different things but I definitly don't get the logic here.
Here is the code :
//Initialize the Scanner earlier
public static Scanner keyBoardRead = new Scanner(System.in);
public static int intEntry()
{
int entry;
keyBoardRead = new Scanner(System.in);
if (keyBoardRead.hasNextInt() == true)
{
entry = keyBoardRead.nextInt();
System.out.println("entry variable = "+entry);
// Here the correct entry prints but doesn't seem to return
return entry;
}
else
{
System.out.println("Invalid entry.\n");
intEntry();
}
return 0;
}
Sample output :
z
Invalid entry.
2
entry variable = 2
// Function exits and output = 0 (?!)
Thanks for your help and please criticize my code :)
I reworked your code a bit as there were a few flaws with it:
public static Scanner keyBoardRead = new Scanner(System.in);
public static int intEntry()
{
int entry;
if (keyBoardRead.hasNextInt())
{
entry = keyBoardRead.nextInt();
System.out.println("entry variable = "+entry);
// Here the correct entry prints but doesn't seem to return
return entry;
}
keyBoardRead.next();
System.out.println("Invalid entry.\n");
return intEntry();
}
Here are the changes explained below:
You do not need to redeclare new Scanner(System.in) with every call
to the method, you state you initially declare it as a class field,
so it should be accessible from inside the method each time.
Your else statement in general is completely unnecessary because you have a return in your if. If your if is executed, it will never enter the code afterward anyway.
You need to return the value from intEntry() with return intEntry() as currently you are just discarding the return value and simply returning 0 unconditionally if else is executed even a single time.
You need to use keyBoardRead.next() if an invalid entry is entered in order to move to the next value and discard the previously entered result. You can also use keyBoardRead.nextLine() instead if you wish to discard the entire line instead.
Using == true on a boolean value is redundant as you can simply check the boolean directly, so if (keyBoardRead.hasNextInt()) instead of if (keyBoardRead.hasNextInt() == true). Credit to #Joop Eggen for catching it.
Example Run:
hi
Invalid entry.
wrong
Invalid entry.
entries
Invalid entry.
55
entry variable = 55
Note: You have a lot of blank space in the output because you are use println and also using \n in the print so it will move to the next line twice.
Also you could easily create a variant to this solution that utilizes a while loop instead of recursion, which is probably a better way to do it so you cannot possibly run into a stack overflow (and is typically easier to read), but I kept the recursion in to keep it similar to your solution.

Why doesn't hasNextInt() method work for large integers?

I'm writing a simple program which receives integer inputs from a Scanner object, determines whether it's a palindrome or not, and returns the boolean value.
For most numbers, it works well. However, at this code snippet:
private static void programRunner() {
System.out.print("Insert your number:");
Scanner in = new Scanner(System.in);
if (in.hasNextInt()) {
int testNumber = in.nextInt();
boolean result = palindromeTester(testNumber);
System.out.println(result);
programRunner();
} else {
System.exit(0);
}
}
I added the "System.exit(0)" expression to make users easily terminate the program by intentionally typing any non-integer value. The problem is that when "considerably large" integers, such as "1234567654321," are provided, the code launches System.exit(0) which means it's not recognized as an integer?
I believe it's the problem lies in the "default radii" of the hasNextInt method, which probably limits the size of integer values it recognizes. (The program runs fine up to 9-digit integers) But I'm not sure. Or is there something wrong with the recursion?
Because an int in Java is 32 bit and can only hold 2^31 - 1 (2147483647) as maximum value (see also Integer.MAX_VALUE).
Anything bigger than that is not int, but long (except if it's even bigger than Long.MAX_VALUE, in which case you need to get the value as BigInteger.)
See Integer.MAX_VALUE, Long.MAX_VALUE,
Scanner.nextInteger(), Scanner.nextLong(),
Scanner.nextBigInteger() and BigInteger.
You can use nextLong() if you have larg "long" integers to read like so :
private static void programRunner() {
System.out.print("Insert your number:");
Scanner in = new Scanner(System.in);
if (in.hasNextLong())
{
long testNumber = in.nextLong();
boolean result = palindromeTester(testNumber);
System.out.println(result);
programRunner();
}
else
{
System.exit(0);
}
}
It seems that you've exceeded the range limit for the int type. the long type seems like what you're looking for.
So, you can either use the hasNextLong() and nextLong() methods of the Scanner class or as #Hovercraft Full Of Eels has suggested in the comments since you're not using the data in a numerical way, it may be better to receive the data as a String instead.
Lastly, but not least I find it inefficient to use recursion here as each recursive call creates a new stack frame along with that for each recursive invocation you're newing up a Scanner instance. it's better to use a while loop instead.

Parsing large int in Java

I have a JTextField object that a user can type in a number(or anything) into. I am trying to parse this textfield for a number and I do a validation check to see if the number is within a certain range (1-999).
String lowerLimit = this.lowerLimitTextField.getText().trim();
String upperLimit = this.upperLimitTextField.getText().trim();
if( Integer.parseInt(lowerLimit) < 1 || Integer.parseInt(upperLimit) > 999 )
{
return "The string must be in the range 0-999";
}
My issue is that, the user can specify any value into the textfield. When I try to input something like "61412356123125124", I get a NumberFormatException when parsing the string. What would be the simplest way to handle such a case? I do have a check that makes sure that the inputted string is all numbers, so thats fine.
I have tried changing the parseInt() into a parseLong() but I still get the same issue, since the number inputted is essentially unbounded. Can this be done with parsing the string (preferred), or is the simplest way to set some constraints on the JTextField itself?
Use NumberFormatto parse
import java.text.NumberFormat;
import java.text.ParseException;
public class MyVisitor {
public static void main(String[] args) throws ParseException {
System.out.println(NumberFormat.getNumberInstance().parse("61412356123125124"));
}
}
outputs
61412356123125124
Looks like you do not want to get the number, just check range (0-999). In this case just catch NumberFormatException and return same string:
try {
if( Integer.parseInt(lowerLimit) < 1 || Integer.parseInt(upperLimit) > 999 ) {
return "The string must be in the range 0-999";
}
} catch (NumberFormatException e) {
return "The string must be in the range 0-999";
//or more relevant message, like "Number to long" or something
}
The answer is that the Exception is your friend: It's telling you the number is too large... Put the error handling in the catch block or better yet declare throws NumberFormatException and catching calling block so that the method can be recalled
So you can use Integer.parseInt, Long.parseLong, or new BigInteger(String)... I would recommend Integer.parseInt in this case. Once you've got an int, you can do bounds checking. And if it's out of bounds, you might just want to throw an NumberFormatException :)

Java get int from string input

Im writing a binary search tree. The user will use the program as follows:
Which tree would you like to test (BST, ST, RBT)?
BST
How many items would you like to insert?
10000
Pattern (random or sorted)?
sorted
Next command (insert X, delete X, find X, height, quit)?
find 111111
Item not present.
For the first three choices i figure i can just use strings to choose between BST, ST and RBT as wel as to choose between random or sorted, somthing like
String choice
if( choice == "random")
insert random numbers
what im having trouble with is the 4th choice. if the user enters insert 100 as a string, for example, would i just have to take the 100 off and make it an int. and if so, how would i go about doing that?
You can use the combination of the functions to determine whether a string is an int or not
public boolean isInteger(String str) {
try {
Integer.parseInt(str);
return true;
} catch(NumberFormatException e) {
return false;
}
}
If this function returns true ... string is an integer ... now get the integer value using
Integer.parseInt(str);
First thing I want to note is that a String should not be compared with ==, rather you should use string.equals(comparedString); You can also use the following code to parse through all the inputs that a person enters, and then use both the string entered and the string value entered and it would not be dependent on the start of the string. This would satisfy the options for them all; insert, delete, ect.
String userInput;//received by system in
String choice;
int choiceInt;
for (int i = 0; i < userInput.length(); i++)
{
Character character = userInput.charAt(i);
if (!Character.isDigit(character))
{
choice += character;
}
else if (Character.isDigit(character))
{
choiceInt += character;
}
else
{
System.out.println("Unable to determine character.");
}
/* Code for the comparison of String based option */
//Example
if (choice.equalsIgnoreCase("insert")//NOTE: the ignore case,
// you want users to be
// able to enter in strings
// and not have a case sensitivity.
{
/* do the code you planned on doing here */
}
}
You could also assign integer values for each String possibility that you are willing to accept as valid options. This would increase the coding but also would also for a switch case statement. (which is still interpreted as if, else if, else statements) I think at that point it would be more up to the developers intentions and design preferences. Please correct me if I am wrong.
You can also replace the final else statement by either using a try and catch block.
Try this:
if (input.startsWith("insert")) {
int num = Integer.parseInt(input.replaceAll("\\D", ""));
}

Need to type "pass" twice to advance

thanks for reading this. I'm creating just a simple, generic version of blackjack using java. Everything else works completely fine, except when it asks you "hit or pass" and you type pass, you must type it twice for it to reconize it, and I cant seem to find out why. Heres my code on pastebin to make it easier to read: http://pastebin.com/GF7Rzusx
Relevant code from pastebin:
public void ask()
{
System.out.println("Hit or Pass?");
if (in.next().equalsIgnoreCase("Hit"))
{
hit();
}
if (in.next().equalsIgnoreCase("Pass"))
{
pass();
}
}
If the entered word is "Pass" it is read from standard input and then lost, it is not stored. It must be stored for it to be available again in the subsequent check:
String input = in.next();
if (input.equalsIgnoreCase("Hit"))
{
hit();
}
else if (input.equalsIgnoreCase("Pass"))
{
pass();
}
Surely you want:
public void ask()
{
System.out.println("Hit or Pass?");
String answer = in.next();
if (answer.equalsIgnoreCase("Hit"))
{
hit();
} else if (answer.equalsIgnoreCase("Pass"))
{
pass();
}
}
Each time you call in.next() it throws away the previous input and expects another token (input).
Example
Imagine what would happen if you had:
System.out.println(in.next());
System.out.println(in.next());
What would it expect as input and what would it output?
Main differences in code
Note that there are two differences in the new code:
You only call in.next() once and so only need one input, which is stored as answer.
You only check whether the answer is "Pass" if it wasn't already "Hit".
See Java Scanner.next documentation.
On row 112 you do:
in.next()
This will read one string token. So if you write pass, this function will return "pass".
The problem is that you do not save this value. Instead, you run in.next() again on row 116, which will require you to write pass yet again.
Instead you would like to store the string returned from in.next() on line 112.
It is because of the way the ask() method is structured. Since you have two if statements, in.next() gets called once when checking if the response is "hit", then a second time when checking for "pass". When you enter "pass", the first if statement calls next(), which returns "pass" and checks if that is equal to "hit", then moves on. Then when the second if statement calls next(), there is no next entry to return, so you have to enter "pass" again. This works when you enter "hit", however, since that is the first case checked.
Refactoring so ask only makes one call to next() should solve the problem.

Categories