I'm playing around with a GUI Sudoku solver that uses an array of JTextFields (gridArray) for display and an int array (sudokuGrid) for the actual solving. When I run it and it tries to cast the JTextField strings to ints, it throws a NumberFormatException on parsing the strings into ints, specifically this message:
java.lang.NumberFormatException: For input string: ""
Here's the section of code that's causing me trouble:
// create solveButton
solveButton = new JButton("Solve It!");
solveButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
try {
// create grid and call Solve()
for(int i=0;i<9;i++) {
for(int j=0;j<9;j++) {
if (gridArray[i][j].getText() == "")
{sudokuGrid[i][j] = 0;}
else {sudokuGrid[i][j] = Integer.parseInt(gridArray[i][j].getText());}
}
} // end for loop
Solver(sudokuGrid);
// display solution
for(int i=0;i<9;i++) {
for(int j=0;j<9;j++) {
gridArray[i][j].setText(String.valueOf(sudokuGrid[i][j]));
}
} // end for loop
} catch (NumberFormatException e) {
JOptionPane.showMessageDialog(mainFrame,e.toString(),"Number Format Exception",JOptionPane.ERROR_MESSAGE);
} catch (Exception e) {
JOptionPane.showMessageDialog(mainFrame,"Sorry, something broke, try again.","Solve Error",JOptionPane.ERROR_MESSAGE);
} // end try-catch
} // end actionPerformed()
}); // end solveButton ActionListener
I thought that the if-else would catch the empty fields and only try the parseInt if there was a value present, but if anyone can enlighten me I'd appreciate it.
Your problem is here:
if (gridArray[i][j].getText() == "")
You can't compare strings that way. Do it this way instead:
if (gridArray[i][j].getText().equals(""))
You are checking string equality using ==, which is only for reference equality. Perhaps you meant to write:
gridArray[i][j].getText().equals("")
Don't ask the TextArea for it's text, since this may be prone to be still in the editing process. Check the underlying document itself.
Document document = gridArray[i][j].getDocument();
sudokuGrid[i][j] = document.getLength() == 0 ? 0 : Integer.parseInt(document.getText(0, 1);
Also... why a JTextArea? Why not a JTextField? You might even combine this with a JSpinner with values from 0 (which is inerpreted as empty to 9.
Using == -comparison with strings does not mean checking for equality of the text (string contents), but instead equality of the String-objects (testing are they the exact same OBJECT). Use String.equals() instead.
The problem is your equality check:
gridArray[i][j].getText() == ""
This does not do what you're intending. In Java this checks whether the two strings are the same object not whether their values are equal.
You should use the String.equals() method to evaluate whether the text field is empty.
Related
Im doing a Java course and in one exercise I have to create three ArrayLists, ask the user to fill the first two with Integers, and then compare both ArrayLists.
The values that donĀ“t repeat are added to the third ArrayList. I already declared the ArrayLists, used Scanner to allow the user to fill the ArrayLists, and that part works.
The problem comes when I try to compare both ArrayLists. I get all sort of alerts in this line ("the if statement is redundant", "Integer values compared using == or !=","Flip operands of the binary operator", "Invert if").
I suspect that what I wrote after the if statement is not very clean, and that I could get some comments about that (Im not an expert in Java), but I do not understand the alerts that the IDE displays. The code compiles and runs just fine until it hits the nested loops. Please help! Thanks.
//Checking for values that dont repeat
for(int i=0;i<listVector1.size();i++){
for(int j=0;j<listVector2.size();i++){
if(listVector1.get(i)==listVector2.get(j)){//Im getting an alert here
repeats=true; //this boolean was previously declared
} else {
repeats=false;
}
if(repeats==false){
int newValue=listVector1.get(i);
listVector3.add(newValue);
}
}
}
First of all, you have a mistake in the second for loop. I expect you want increment j.
Second is comparing you must explicit cast your values from the array or use function equals.
Third your if statement must be out of your second loop. Because I expect you want to add number in third array only one time as it you find.
for(int i = 0; i < listVector1.size(); i++) {
for(int j = 0; j < listVector2.size(); j++) {
if (listVector1.get(i).equals(listVector2.get(j))) {
repeats = true;
break;
} else {
repeats = false;
}
}
if(!repeats){
int newValue=listVector1.get(i);
listVector3.add(newValue);
}
}
This is the real problem here.
Integer values compared using == or !=
The == operator compares the two object's reference. But what you actually want to do is compare the values stored in the reference.
So, you need to use the equals operator.
Or you could explicitly cast one of the values to int and use == on the values like
if(listVector1.get(i) == ((int)listVector2.get(j))){
repeats=true;
} else {
repeats=false;
}
For more reading, you'd google difference between == and equals operator.
This question already has answers here:
What's the best way to check if a String represents an integer in Java?
(40 answers)
Closed 9 years ago.
I'm trying to determine if a particular item in an Array of strings is an integer or not.
I am .split(" ")'ing an infix expression in String form, and then trying to split the resultant array into two arrays; one for integers, one for operators, whilst discarding parentheses, and other miscellaneous items. What would be the best way to accomplish this?
I thought I might be able to find a Integer.isInteger(String arg) method or something, but no such luck.
The most naive way would be to iterate over the String and make sure all the elements are valid digits for the given radix. This is about as efficient as it could possibly get, since you must look at each element at least once. I suppose we could micro-optimize it based on the radix, but for all intents and purposes this is as good as you can expect to get.
public static boolean isInteger(String s) {
return isInteger(s,10);
}
public static boolean isInteger(String s, int radix) {
if(s.isEmpty()) return false;
for(int i = 0; i < s.length(); i++) {
if(i == 0 && s.charAt(i) == '-') {
if(s.length() == 1) return false;
else continue;
}
if(Character.digit(s.charAt(i),radix) < 0) return false;
}
return true;
}
Alternatively, you can rely on the Java library to have this. It's not exception based, and will catch just about every error condition you can think of. It will be a little more expensive (you have to create a Scanner object, which in a critically-tight loop you don't want to do. But it generally shouldn't be too much more expensive, so for day-to-day operations it should be pretty reliable.
public static boolean isInteger(String s, int radix) {
Scanner sc = new Scanner(s.trim());
if(!sc.hasNextInt(radix)) return false;
// we know it starts with a valid int, now make sure
// there's nothing left!
sc.nextInt(radix);
return !sc.hasNext();
}
If best practices don't matter to you, or you want to troll the guy who does your code reviews, try this on for size:
public static boolean isInteger(String s) {
try {
Integer.parseInt(s);
} catch(NumberFormatException e) {
return false;
} catch(NullPointerException e) {
return false;
}
// only got here if we didn't return false
return true;
}
It's better to use regular expression like this:
str.matches("-?\\d+");
-? --> negative sign, could have none or one
\\d+ --> one or more digits
It is not good to use NumberFormatException here if you can use if-statement instead.
If you don't want leading zero's, you can just use the regular expression as follow:
str.matches("-?(0|[1-9]\\d*)");
Or you can enlist a little help from our good friends at Apache Commons : StringUtils.isNumeric(String str)
You want to use the Integer.parseInt(String) method.
try{
int num = Integer.parseInt(str);
// is an integer!
} catch (NumberFormatException e) {
// not an integer!
}
Or simply
mystring.matches("\\d+")
though it would return true for numbers larger than an int
As an alternative approach to trying to parse the string and catching NumberFormatException, you could use a regex; e.g.
if (Pattern.compile("-?[0-9]+").matches(str)) {
// its an integer
}
This is likely to be faster, especially if you precompile and reuse the regex.
However, the problem with this approach is that Integer.parseInt(str) will also fail if str represents a number that is outside range of legal int values. While it is possible to craft a regex that only matches integers in the range Integer.MIN_INT to Integer.MAX_INT, it is not a pretty sight. (And I am not going to try it ...)
On the other hand ... it may be acceptable to treat "not an integer" and "integer too large" separately for validation purposes.
You can use Integer.parseInt(str) and catch the NumberFormatException if the string is not a valid integer, in the following fashion (as pointed out by all answers):
static boolean isInt(String s)
{
try
{ int i = Integer.parseInt(s); return true; }
catch(NumberFormatException er)
{ return false; }
}
However, note here that if the evaluated integer overflows, the same exception will be thrown. Your purpose was to find out whether or not, it was a valid integer. So its safer to make your own method to check for validity:
static boolean isInt(String s) // assuming integer is in decimal number system
{
for(int a=0;a<s.length();a++)
{
if(a==0 && s.charAt(a) == '-') continue;
if( !Character.isDigit(s.charAt(a)) ) return false;
}
return true;
}
You can use Integer.parseInt() or Integer.valueOf() to get the integer from the string, and catch the exception if it is not a parsable int. You want to be sure to catch the NumberFormatException it can throw.
It may be helpful to note that valueOf() will return an Integer object, not the primitive int.
public boolean isInt(String str){
return (str.lastIndexOf("-") == 0 && !str.equals("-0")) ? str.substring(1).matches(
"\\d+") : str.matches("\\d+");
}
I need to parse an input string for an application and have a question related to how java evaluates the result of the string split() method.
For example, in the code bellow:
} else if (arg.equals("-multiplePaths")) {
// Check if we have multiple paths
if (args[count++].contains(":")) {
for(String tmpIDLPath : args[count-1].split(":"))
m_includePaths.add(tmpIDLPath);
} else {
// Only one
m_includePaths.add(args[count-1]);
}
how is for loop evaluated? Is the split operation computed once for each iteration or once at the beginning?
The array you are looping over is computes once per loop.
BTW Your check is redundant.
} else if (arg.equals("-multiplePaths")) {
for(String tmpIDLPath : args[count-1].split(":"))
m_includePaths.add(tmpIDLPath);
or
} else if (arg.equals("-multiplePaths")) {
Collections.addAll(m_includePaths, args[count-1].split(":"));
I want to add text to the EditText without losing the previous text.
Ex: when typing 74, i want to add the "4" to the text box without erasing the number "7" entered before.
public void add4()
{
res = (EditText)findViewById(R.id.editText1);
if(res.getText().toString() == "0")
{
res.setText("4");
}
else
{
// add number 4 to the remaining string
}
}
You can use the append method to append to existing text.
res.append("4");
http://developer.android.com/reference/android/widget/TextView.html#append(java.lang.CharSequence)
(As a side note, don't use == to compare strings, use .equals())
Try this:
I used the .equals method on a string object to avoid the NullPointerException that may happen if the object is null or not a string.
public void add4() {
res = (EditText)findViewById(R.id.editText1);
if( "0".equals(res.getText().toString()) )
{
res.setText("4");
}
else
{
res.append("4");
}
}
res.append("4"); or you can use res.setText(res.getText() + "4");
I want to read a data stream and everytime it reads a certain word or phrase I want the count to go up. The example I have below fails to count it. I tried looking for "echo percent" as well. All the bat file does is echo percent.
try {
String ls_str;
String percent = "percent";
Process ls_proc = Runtime.getRuntime().exec("c:\\temp\\percenttest.bat");
// get its output (your input) stream
DataInputStream ls_in = new DataInputStream(ls_proc.getInputStream());
while ((ls_str = ls_in.readLine()) != null ) {
System.out.println(ls_str);
progressBar.setValue(progress);
taskOutput.append(String.format(ls_str+"\n", progress));
if (ls_str == percent) {
progress++;
}
}
} catch (IOException e1) {
System.out.println(e1.toString());
e1.printStackTrace();
}
setProgress(Math.min(progress, 100));
DataInputStream.readLine is deprecated. Use BufferedReader and its readLine method or Scanner and nextLine instead. Also, use .equals to compare two strings, not ==.
The == comparison only does a reference comparison, asking the question, "Are these two strings in the same place in memory?" Usually, the answer is "no." On the other hand, equals asks the question, "Are the characters in these two strings the same?" This is called deep comparison, and the == operator doesn't perform the deeper comparison.
Don't compare the Strings with ==, use the equals method.
If you compare the Strings with ==, you're checking to see if they're the same String.
If you compare them with equals, you're checking whether or not their contents are the same.
Instead of:
if (ls_str == percent)
Do this:
if (ls_str.equals(percent))
If you want to ignore case, you can do it like this:
if (ls_str.equalsIgnoreCase(percent))
EDIT
Your String format is also messed up.
Change:
taskOutput.append(String.format(
ls_str+"\n", progress));
to:
taskOutput.append(String.format(
ls_str+"\n"), progress);
Notice the parentheses change.
Take a look at these for more explanations:
Java String.equals versus ==
http://www.java-samples.com/showtutorial.php?tutorialid=221