Improve condition check - java

Need best approach in the following scenario,
I've list of attributes like source , destination, Yes/No as below:
Example:
source , destination , Yes/No
abc, bcd, Yes
abd, gdc, Yes
In java i can go with condition like
if(Obj.getSource().equals("abc")) {
if(Obj.getDest().equals("bcd")) {
return true;
}
}
if(Obj.getSource().equals("abd")) {
if(Obj.getDest().equals("gdc")) {
return true;
}
}
In this way i can handle the above case , based on the resultant Yes , i can handle my business logic.
But my approach was two many check and , lines of codes to lengthy,
Please suggest me good approach in java7 or java8.

You can just combine all four conditions into one using logical operators. For example by using logical and && and logical or ||. It could then look like:
if ((first && second) || (third && fourth)) {
return true;
}
Or with all conditions substituted:
if ((Obj.getSource().equals("abc") && Obj.getDest().equals("bcd"))
|| (Obj.getSource().equals("abd") && Obj.getDest().equals("gdc"))) {
return true;
}
Note that you may memorize the result of Obj.getSource() and Obj.getDest() in a variable in order to save some performance and make the condition more readable by using that variable instead.
And if you would return false; in the other cases you could even completely leave out the whole if as you could directly return the boolean resulting after evaluating the condition (it evaluates to either true or false, no need to return true and false hardcoded then):
return (first && second) || (third && fourth);

Related

How to put 2 condition in one statement actiolistener in java? [duplicate]

I'm a beginner in coding. I was recently working with to create a chatting programme where a user will chat with my computer. Here is a part of the code:
System.out.println("Hello, what's our name? My name is " + answer4);
String a = scanner1.nextLine();
System.out.println("Ok, Hello, " + a + ", how was your day, good or bad?");
String b = scanner2.nextLine();
**if (b.equals("good"))** { //1
System.out.println("Thank goodness");
} else **if (b.equals("it was good"))** { //2
System.out.println("Thank goodness");
} else **if (b.equals("bad"))** { //3
System.out.println("Why was it bad?");
String c = scanner3.nextLine();
System.out.println("Don't worry, everything will be ok, ok?");
String d= scanner10.nextLine();
} else **if (b.equals("it was bad"))**{ //4
System.out.println("Why was it bad?");
String c = scanner3.nextLine();
System.out.println("Don't worry, everything will be ok, ok?");
String d= scanner10.nextLine();
}
if(age<18){System.out.println("How was school?");}
else if (age>=18){System.out.println("How was work?");}
The conditions of the if statements are in Bold (surrounded with **). In case of first and the second condition I want my application to do same thing. Similarly third and fourth condition. I thought it was possible to somehow group them in if statement.
I tried with below code but it doesn't compile:
if (b.equals("good"), b.equals("it was good")) {
System.out.println("Thank goodness");
} else if (b.equals("bad"),(b.equals("it was bad"))) {
System.out.println("Why was it bad?");
String c = scanner3.nextLine();
System.out.println("Don't worry, everything will be ok, ok?");
String d= scanner10.nextLine();
}
Can someone correct it for me?
You can use logical operators to combine your boolean expressions.
&& is a logical and (both conditions need to be true)
|| is a logical or (at least one condition needs to be true)
^ is a xor (exactly one condition needs to be true)
(== compares objects by identity)
For example:
if (firstCondition && (secondCondition || thirdCondition)) {
...
}
There are also bitwise operators:
& is a bitwise and
| is a bitwise or
^ is a xor
They are mainly used when operating with bits and bytes. However there is another difference, let's take again a look at this expression:
firstCondition && (secondCondition || thirdCondition)
If you use the logical operators and firstCondition evaluates to false then Java will not compute the second or third condition as the result of the whole logical expression is already known to be false. However if you use the bitwise operators then Java will not stop and continue computing everything:
firstCondition & (secondCondition | thirdCondition)
Here are some common symbols used in everyday language and their programming analogues:
"," usually refers to "and" in everyday language. Thus, this would translate to the AND operator, &&, in Java.
"/" usually refers to "or" in everyday language. Thus, this would translate to the OR operator, ||, in Java.
"XOR" is simply "x || y but both cannot be true at the same time". This translates to x ^ y in Java.
In your code, you probably meant to use "or" (you just used the incorrect "incorrect solution" :p), so you should use "||" in the second code block for it to become identical to the first code block.
Hope this helped :)
You're looking for the "OR" operator - which is normally represented by a double pipe: ||
if (b.equals("good") || b.equals("it was good")) {
System.out.println("Thank goodness");
} else if (b.equals("bad") || b.equals("it was bad")) {
System.out.println("Why was it bad?");
String c = scanner3.nextLine();
System.out.println("Don't worry, everything will be ok, ok?");
String d= scanner10.nextLine();
}
This is probably more answer than you need at this point. But, as several others already point out, you need the OR operator "||". There are a couple of points that nobody else has mentioned:
1) If (b.equals("good") || b.equals("it was good")) <-- If "b" is null here, you'll get a null pointer exception (NPE). If you are genuinely looking at hard-coded values, like you are here, then you can reverse the comparison. E.g.
if ("good".equals(b) || "it was good".equals(b))
The advantage of doing it this way is that the logic is precisely the same, but you'll never get an NPE, and the logic will work just how you expect.
2) Java uses "short-circuit" testing. Which in lay-terms means that Java stops testing conditions once it's sure of the result, even if all the conditions have not yet been tested. E.g.:
if((b != null) && (b.equals("good") || b.equals("it was good")))
You will not get an NPE in the code above because of short-circuit nature. If "b" is null, Java can be assured that no matter what the results of the next conditions, the answer will always be false. So it doesn't bother performing those tests.
Again, that's probably more information than you're prepared to deal with at this stage, but at some point in the near future the NPE of your test will bite you. :)
You can have two conditions if you use the double bars(||). They mean "Or". That means only ONE of your conditions has to be true for the loop to execute.
Something like this:
if(condition || otherCondition || anotherCondition) {
//code here
If you want all of conditions to be true use &&. This means that ALL conditions must be true in order for the loop to execute. if any one of them is false the loop will not execute.
Something like this:
if(condition && otherCondition && anotherCondition) {
//code here
You can also group conditions, if you want certain pairs of them to be true. something like:
if(condition || (otherCondition && anotherCondition)) {
//code here
There is a simpler way.
if (b.contains("good")) {
...
}
else if (b.contains("bad")) {
...
}

java new file not returning a boolean when part of a conditional

In my Java program, this creates a directory and returns a boolean true when successful:
new File(String.valueOf(subdir)).mkdir();
So why does that not work as the second part of this boolean? I.e., the directory does not get created and it does nt return a boolean true.
if (!subdir.exists() || new File(String.valueOf(subdir)).mkdir()) {
logger.error("subdir not created");
}
The second condition won't be calculated if the first condition is already true and the conditions are joined with OR || operator.
Similarly, second condition is not calculated for AND && operator if the first condition is false.
It is so called short circuit for logical operations - because it does not make sense to continue evaluation of other terms if the result of the expression is already defined:
false && any_operand == false
true || any_operand == true
So, in your case you need to use && in the condition and possibly use File::mkdirs() method to create parent directories if they don't exist:
if (!maint.exists() && !maint.mkdirs()) {
logger.info("no directories {} created", maint);
}

How to sort list of strings where first comes strings with startWith then endWith

I have list of Strings
for example
**united**abc
**united**abcd
abcd**united**
**united**abcde
asdasdad**united**
**united**a
it is sorted based on length of the strings, but my idea is to sort like
**united**a
**united**abc
**united**abcd
**united**abcde
abcd**united**
asdasdad**united**
so first comes strings where start with united and then others words ending with united. but I still need to keep the length order as well.
I tried this but this doesn't work
if (o1.name.toLowerCase().startsWith(query)) {
return#Comparator -1
} else if (o2.name.toLowerCase().startsWith(query)) {
return#Comparator 1
} else {
return#Comparator 0
}
It will be a lot more legible and thus less error-prone to combine comparator conditions using the Comparator.comparing and thenComparing methods:
list.sort(Comparator.comparing((String str) -> !str.startsWith(query))
.thenComparing(str -> !str.endsWith(query))
.thenComparingInt(String::length)
.thenComparing(Comparator.naturalOrder()));
The reason for the ! symbol is so that our trues will sort before falses.
The problem with your comparer is that it violates constraints when both inputs either start or end in query string. For example, when both o1 and o2's name start in "united", your comparer would return -1 both for o1.compareTo(o2) and its opposite o2.compareTo(o1), which is inconsistent, and therefore throws off the sorting algorithm.
You need to modify the code to check both sides for startsWith and endsWith before you proceed further:
String n1 = o1.name.toLowerCase();
String n2 = o2.name.toLowerCase();
// Both startsWith / both endsWith
if ((n1.startsWith(query) && n2.startsWith(query))
|| (n1.endsWith(query) && n2.endsWith(query))) {
return Integer.compare(n1.length(), n2.length());
}
// Only one startsWith
if (n1.startsWith(query)) {
return -1;
}
if (n2.startsWith(query)) {
return 1;
}
// only one endsWith
if (n1.endsWith(query)) {
return 1;
}
if (n2.endsWith(query)) {
return -1;
}
You need 3 comparators for readabilty.
One to find out if united is in the front and then order by that.
One to find out if united is in the back and then order by that.
One to find order if united isn't contained, or both have the same united priority eg. o1.unitedFront && o2.unitedFront or o1.unitedEnd && o2.unitedEnd.
You are currently not thinking about cases where both strings contain united, because you assume that if the first does, then other doesn't.

Conditions in Ternary Operator - Java

I have a simple if/elseif condition which I'm trying to convert it into a return statement with Ternay Operator for code redundancy but I have not been able to.
Any help would be appreciated, Thanks.
Here's my code snippet :
if (val.equals("a")||val.equals("s")){
return true;
}
else if (val.equals("b")||val.equals("t")) {
return false;
}
return true;
Could someone please suggest on how to proceed with return statement(Ternary Operator) for the above if/else-if ?
There's no need for a conditional operator here. Your code will return true so long as val is neither b nor t:
return !(val.equals("b") || val.equals("t"));
or:
return !val.equals("b") && !val.equals("t");
The first condition around a and s is completely irrelevant, as the "default" return true at the bottom already includes those cases.
EDIT: Now that you've changed the return type to int, this would be reasonable to use with the conditional operator:
return val.equals("b") || val.equals("t") ? 0 : 1;
return !(val.equals("b") || val.equals("t"))
The rest is redundant, val cannot equal "a" or "s" and equal "b" or "t" at the same time, so you basically need to check if it equals "b" or "t", and return false in this case, and true in any other case.
return !(val.equals("b") || val.equals("t"));
This is the only condition that returns false - so you don't need to check the first condition.
return !(val.equals("b") || val.equals("t"))
Try the follwing:
boolean b = ( val.equals("b") || val.equals("t") ) ? false : true;
return b;

Do while loop comparing Strings

I'm trying to do a "do while" loop with a nested if statement. I'm trying to compare two possible values for a String variable "word". If !word.equals "deeppan or thin" do something, else do something. But its not liking me using the or || comparator .. Any suggestions would be welcome.
do {
word = scan.next();
if ( !word.equalsIgnoreCase( "Deeppan" || "thin" ) ) {
System.out.print("Sorry you must specify a Deeppan or thin base, try again: ");
} else {
break;
}
} while ( true );
equalsIgnoreCase takes a single string argument, not a logical expression. You can combine them with || or && though:
if (!word.equalsIgnoreCase( "Deeppan") && !word.equalsIgnoreCase("thin" ))
You have to do it like this:
if (!word.equalsIgnoreCase("Deeppan") && !word.equalsIgnoreCase("thin")) {
Think about the || which i switched to &&, because the if should only be true, if the value is not the first AND not the second one!
This part is wrong, that's not how you use the boolean || operator, and anyway the logic is incorrect:
if (!word.equalsIgnoreCase("Deeppan" || "thin"))
It should be like this, comparison-operator-comparison, and notice the correct way to state the comparison for the effect you want to achieve:
if (!(word.equalsIgnoreCase("Deeppan") || word.equalsIgnoreCase("thin")))
Or equivalently, using De Morgan's laws (and easier to read and understand, IMHO):
if (!word.equalsIgnoreCase("Deeppan") && !word.equalsIgnoreCase("thin"))
You have a few issues going on. First:
"Deeppan" || "thin"
is attempting to use the boolean "OR" operator to compare two strings. The "OR" operator can only compare boolean results and returns a boolean that is the result of the comparison:
System.currentTimeMillis() == 123455667 || object.equals(this) // both sides are boolean results.
true || false // returns 'false'
But let's pretend for a second that "Deeppan" || "thin" is OK (remember, it isn't) and the compiler knows that you want to compare the two strings. It still leaves the issue that the OR operator returns a boolean result (true or false), which you are then attempting to pass into the method equalsIgnoreCase on the word variable. equalsIgnoreCase takes a String argument, not a boolean. This is the second compilation issue. As has been pointed out, what you need is to check for the conditions separately and OR the result to get the final boolean
if("Deeppan".equalsIgnoreCase(word) || "thin".equalsIgnoreCase(word)) {
// do something
}
("Deeppan" || "thin")
is a boolean expression. equalisIgnoreCase takes a string. Therefore you need to make two seperate calls and OR the (boolean) results

Categories