JAVA Comparing two Strings isn't working - java

So here's a snippet of code I'm working on:
String direction = s.readLine();
System.out.println(direction);
if (direction.equals("up") != true && direction.equals("down") != true &&
direction.equals("left") != true && direction.equals("right") &&
direction.equals(null) != true) {
System.out.println("Invalid Solution file");
System.exit(0);
}
What it is supposed to do is read a line from a text file (using a BufferedReader) and then if the line isn't either a valid direction or blank then it should print "Invalid Solution" and exit.
The problem is that no matter what the direction string is the if statement still runs. I put in a println to check whether the direction was being read correctly but it seems absolutely fine. So why isn't the code working as intended?

Part of your problem is readability. Fix that and your problem is 90% solved:
private static List<String> DIRECTIONS = Arrays.asList("up", "down", "left", "right");
then
if (!DIRECTIONS.contains(direction)) {
System.out.println("Invalid Solution file");
System.exit(0);
}
The other 10% was how to check for null, which is direction == null, but if you use this code you don't need to, because contains(null) will conveniently return false.

You code is much more complex than it is needs to.
Consider this instead:
Set<String> validDirections = new HashSet<>(Arrays.asList("up", "down", ...
if (validDirections.contain(direction.toLowerCase()) {
// good ...
} else {
// bad ..
}
You can make validDirections a global constant for example; so it could be used in other places as well.
What I am trying to explain here is: your code is low-level. Low level code is hard to write, read, maintain and extend. Programming is always about creating good abstractions. Or vice versa: if you don't use abstractions, you end up with pretty abstract code, like the one you are showing here!
For example: if you need another direction, you have to put into your already way too complicated if condition. In my solution, you just put it into the statement that builds that Set.
Finally: your error message, is saying nothing. So, that string is bad; but why is it? Wouldn't it be better to at least print the string that caused the error?!

Here && direction.equals("right") I think you have done a mistake since it is on contradiction with the rest :
direction.equals("up") != true &&
direction.equals("down") != true &&
direction.equals("left") != true
You test the negation in the most of conditions but direction.equals("right") tests the affirmation.
Try it , it's the same thing but less verbose and more readable :
if (direction !=null && !direction.equals("up") &&
!direction.equals("down") &&
!direction.equals("left") &&
!direction.equals("right") ){
System.out.println("Invalid Solution file");
System.exit(0);
}

First, you should not use != true with a boolean statement, it is bad form. Rewrite like this:
direction !=null &&
!direction.equals("up") &&
!direction.equals("down") &&
!direction.equals("left") &&
!direction.equals("right")
Your error was that you did not include the != true part on one of your statements within the compound if. Replace with the above code to solve the issue.

I'm confused why you are using !=true when your .equals method already returns a boolean. Try this.
String direction = s.readLine();
System.out.println(direction);
if ( direction!=null && !direction.equals("up") && !direction.equals("down")&& !direction.equals("left")&& direction.equals("right")){
System.out.println("Invalid Solution file");
System.exit(0);
}

Try the following code:
boolean match = false;
if (direction.equals("up"))
{ match = true; }
if (direction.equals("down"))
{ match = true; }
if (direction.equals("left"))
{ match = true; }
if (direction.equals("right"))
{ match = true; }
if (direction.equals(null))
{ match = true; }
if (match == false){
System.out.println("Invalid Solution file");
System.exit(0);
}
You might also want to trim the direction string after reading from file.

The quals method returns a boolean so the result does not need to be compared with the true or false value. Also, I would start with null comparison - boolean expressions in Java are shortened so if this part will be fulfilled rest of the expression is not evaluated. The correct expression might look like this:
 
if (direction == null || (!direction.equals("up") && !direction.equals("down") && !direction.equals("left") && !direction.equals ("right "))) {
}
But this code is not readable. You could use enums or list of Strings like below
List<String> directions = Arrays.asList("up", "down", "left", "right");
String direction = "readValue"
if (!directions.contains(direction)) {
System.out.println("Invalid direction");
System.exit(0)
}

Related

Java checkbox with AND operator

Please, I want to use the AND operator with checkbox in creating different options.
if (chkd.isSelected()){
lbl.setText("hello");
}
else if (chkd.isSelected() && chkm.isSelected()){
lbl.setText("cool");
}
Please, what's the best approach to do this. I am using Eclipse for Java.
As written, assuming chkd and chkm are defined won't work because if the if statement is true, the else if won't execute.
Try this instead:
if (chkd.isSelected()) {
if (chkm.isSelected()) {
lbl.setText("cool");
} else {
lbl.setText("hello");
}
}
What's happening is we're checking chkd is true, we then check to see if chkm is true we're cool, otherwise, we're hello.
Alternatively you can turn around your if statement.
So checking first for the (a && b) Statement will give you the cool value. If the && is not true, your other Statement (hello) will be displayed.
if (chkd.isSelected() && chkm.isSelected()) {
lbl.setText("cool");
} else if {
lbl.setText("hello");
}

Determine if a string that contains parentheses is balanced

This is an school assignment ive been trying to solve for a week, i still havent gotten close to the real answer. If someone is so kind and guides me with some solid pointers it would be really apreciated, Notice i do not want the solution.
For example, the strings () , [()] , {([])} , ()[] are 4 balanced strings.
Write the Recursive method:`
public static boolean isBalanced(String in)
that returns true if in is a balanced parentheses string and
false if it is not.
Here is some of the code ive been working on:
public static boolean isBalanced(String in){
if(in.length() == 0){
return true;
}
char aux = in.charAt(0);
if(aux == '{' ||aux == '[' ||aux == '(' ){
if(aux == '{'){
return isBalanced(in.substring(1));
}
if(aux == '}'){
return false || isBalanced(in.substring(1));
}
if(aux == '['){
return isBalanced(in.substring(1));
}
if(aux == ']'){
return false || isBalanced(in.substring(1));
}if(aux == '('){
return isBalanced(in.substring(1));
}
if(aux == ')'){
return false || isBalanced(in.substring(1));
}
}
return isBalanced(in.substring(1));
}
}
Since you do not want a copy&paste solution, you should check out this post:
https://stackoverflow.com/a/25854415/1057547
it is written in PHP, but exlains the idea behind, which you can adapt easily.
The page to "validate" your input is still available: http://dog-net.org/string.php, so you can test "huge" strings without doing paperwork.
As of your comments, you require to implement an recursive approach. So, with the given signature of isbalanced(String str) There are two options in my mind to generate a recursive approach:
First, you could - in the first recursion call - iterate over the string using the described ways, until you are balanced but have a remaining string. Then you just need to recursivly call the method on the remaining string.
So, for the input String () [()]{([])}()[] the callstack should become:
isBalanced("()[()]{([])}()[]");
isBalanced("[()]{([])}()[]");
isBalanced("{([])}()[]");
isBalanced("()[]");
isBalanced("[]");
This however will not go into recursion for strings like {([])} - because they could be handled within one call.
The second way would be to enter recursion depending on "characters". So, you always seek for the matching bracket of the first opening bracket within ONE recursion call, replace both and continue with another call. This would be a slower solution - performance-wise - but allows recursion with the given signature.
The callstack then should look like:
isBalanced("()[()]{([])}()[]");
isBalanced("__[()]{([])}()[]");
isBalanced("___()_{([])}()[]");
isBalanced("______{([])}()[]");
isBalanced("_______([])_()[]");
isBalanced("________[]__()[]");
isBalanced("____________()[]");
isBalanced("______________[]");
isBalanced("________________");
ps.:
No matter what you do, don't forget to add
isBalanced(String str){
if (str.length() % 2 != 0) return false;
...
}
for the "A+" :-)

Failed text validation

I have a snippet of code that consistently gives me an error:
do {
System.out.println("Choose Role: (Manager, Developer, QA) ");
role = scan.nextLine();
// For testing: ///////////////////////
System.out.println("role is: " + role);
////////////////////////////////////////////////
if (is_numeric(role)) {
System.out.println("Invalid Input.");
continue;
} else if (!role.equalsIgnoreCase("MANAGER") || !role.equalsIgnoreCase("DEVELOPER") || !role.equalsIgnoreCase("QA")) {
System.out.println("Invalid Role");
continue;
} else {
break;
}
} while (true);
I added the "For testing" block just to see, if for some reason there is something happening to the variable role, but its not. No matter how I write manager/developer/qa (whether in caps, small letters, etc) the "Invalid Role" is triggered and the loop goes over again.
Any suggestions?
Logically, this test is wrong
(!role.equalsIgnoreCase("MANAGER") ||
!role.equalsIgnoreCase("DEVELOPER") ||
!role.equalsIgnoreCase("QA"))
Why? Because if the role = "MANAGER", it does not equal "DEVELOPER" (or "QA") and vice-versa. I think you wanted
(!role.equalsIgnoreCase("MANAGER") &&
!role.equalsIgnoreCase("DEVELOPER") &&
!role.equalsIgnoreCase("QA"))
!role.equalsIgnoreCase("MANAGER") || !role.equalsIgnoreCase("DEVELOPER") ||
!role.equalsIgnoreCase("QA")
Is not what you want, replace || with &&.
In your code you're saying: If role is not "MANAGER" OR if role is not "DEVELOPER" OR if role is not "QA".
Due to Short-circuit evaluation, if the first condition is true, the others won't be evaluated because true || anything is always true.
Java if test short circuit for boolean expressions.
Change || to &&
Contrary to what everyone else is saying, if what you're trying to model is "not valid", then don't distribute the negative over each condition and use &&. It's not modelling the right thing. Model "valid", put parentheses around it and negate the whole thing:
if (!(role.equalsIgnoreCase("MANAGER") || role.equalsIgnoreCase("DEVELOPER") ||
role.equalsIgnoreCase("QA"))) {
//...
}
But this is a case where a helper method will improve code clarity greatly. First model what you want to model, not the inverse:
public boolean validRole(String role) {
return role.equalsIgnoreCase("MANAGER") ||
role.equalsIgnoreCase("DEVELOPER") ||
role.equalsIgnoreCase("QA");
}
Then your if statement is hard to get wrong and documents itself:
if (!validRole(role)) {
//...
}

File/Scanner simple parsing issues

Given a File and a Scanner object,
File simpleFile = ranFi.getSelectedFile();
Scanner text = new Scanner(simpleFile);
and these two commonplace statements:
while(text.hasNext())
{
String currentLine = text.nextLine();
I'm trying to use Scanner/String class logical statements in a single if-statement clause which reads first line of file under a given matching regular expressions, such as:
String fp100 = "[S][:][A-Ze0-1]";
String fp200 = "[S][:][A-Z0-1][A-Z0-1]";
//other regexes…
and then invoke the appropriate Scanner/String class methods in same if-statement clause to read to second and onward/acceptable lines. I've read javadoc up and down but haven't figured out yet. Using currentLine.matches(regex) and text.nextLine().matches(regex), this code compiled,
if(currentLine.matches(fp100)||currentLine.matches(fp200)||
currentLine.matches(fp300) && text.nextLine().matches(fp100)||
text.nextLine().matches(fp101) || text.nextLine().matches(fp200)||
text.nextLine().matches(fp201) || text.nextLine().matches(fp300)||
text.nextLine().matches(fp301))
{
but throws an No Such Element Exception immediately. What am I doing wrong?
Thank you in advance for your time. EDIT: I've included the stack trace, but removed the source code since this is project related.
I see two problems:
When you perform the if condition, text.nextLine() may not be available.
if you mean to say, execute the if when any of the currentLine Matches + any of the nextLine match as true then wrap || arguments in a brace as:
if((currentLine.matches(fp100)||currentLine.matches(fp200)||
currentLine.matches(fp300)) &&
(text.nextLine().matches(fp100)||
text.nextLine().matches(fp101) || text.nextLine().matches(fp200)||
text.nextLine().matches(fp201) || text.nextLine().matches(fp300)||
text.nextLine().matches(fp301)))
I think you wanted to write your while loop something like this:
while(text.hasNextLine()){
String currentLine = text.nextLine();
String nextLine = "";
if(text.hasNextLine())[
nextLine = text.nextLine();
}
/**ACC conditions*/
if((currentLine.matches(fp100)||currentLine.matches(fp200)
|| currentLine.matches(fp300))
&& (nextLine.matches(fp100)|| nextLine.matches(fp101)
|| nextLine.matches(fp200)
|| nextLine.matches(fp201) || nextLine.matches(fp300)
|| nextLine.matches(fp301)) {
//current line is OK
System.out.println(currentLine);
output.write(currentLine);
output.write("\n");
abc1List.add(currentLine);
lineOK++;
//next line is OK
System.out.println(nextLine);
output.write(nextLine);
output.write("\n");
abc1List.add(nextLine);
// <-- not sure if you want OK as 1 or 2 here
lineOK++;
} /**REJ conditions*/
else if(!currentLine.matches(fp100)||!currentLine.matches(fp101)||
!currentLine.matches(fp200)||!currentLine.matches(fp201)||
!currentLine.matches(fp300)||!currentLine.matches(fp301)){
System.out.println("invalid cfg; terminating....");
System.exit(0);
}
}//end of while
Your while loop should start with while(text.hasNextLine()) if you are using text.nextLine().matches(regex) inside the loop. Be careful. If text.hasNext() evaluates to true, it doesn't mean that text.nextLine() will be non-null.

Java Nonworking method?

Hey,
So Ive got this method to determine if a game I wrote is over and for some reason it isn't working. I'm getting the error "the left hand side of assignment must be a variable"
Here is the method:
public boolean isWinner() {//checks for game completion
int check = board[startX][startY];
for(int i=0; i<sizeX; i++){
for(int j=0; j<sizeY; j++){
if (board[i][j] != check)
return false;
}
}
return true;
}
Here is a piece of the code where it is used:
ColorFloodGame game = new ColorFloodGame (6,6);
while (game.isWinner() = false){
//code here
}
You have while (game.isWinner() = false), which is an assignment because you have a single = sign.
You want while (game.isWinner() == false) which is a comparison because it has two = signs.
You need to replace
while (game.isWinner() = false){
with
while (game.isWinner() == false){
or better yet:
while (!game.isWinner()){
while (game.isWinner() = false){
should be
while (game.isWinner() == false){
one '=' is an assignment, two '==' is a comparison
Ralf & Gabe have already answered it, but IMHO this is more readable:
while (!game.isWinner()){
The expression in the while statement is an assignment. The compiler can't evaluate the expression correctly. Change your code to the following and everything should work fine.
while (game.isWinner() == false) {
//code here
}
You could also write the code like this
while (!game.isWinner()) {
//code here
}
The style used is different for every programmer and you should find your own preference.
Hope it helps.

Categories

Resources