In a program I am trying to check two boolean values (returned from a function); the condition that needs to be checked is:
- only if any one of the returned value is true and the other is false then I have a problem;
- else if both are true or false I am good to go to next step.
Which of the following two examples would be the efficient way to check the condition, or is there a better solution?
a and b are integer values on which I am checking a condition for correctness in isCorrect function and it return true or false.
1.
// checking for the correctness of both a and b
if ((isCorrect(a) && !isCorrect(b)) ||
(!isCorrect(a) && isCorrect(b)))
{
// a OR b is incorrect
}
else
{
// a AND b are both correct or incorrect
}
2.
// checking for the correctness of both a and b
if (! (isCorrect(a) ^ isCorrect(b)))
{
// a OR b is incorrect
}
else
{
// a AND b are correct or incorrect
}
Thanks,
Ivar
P.S: code readability is not an issue.
EDIT: I meant to have an XOR in the second option.
Also, I agree with the == and != options, but what if I had to use boolean operators?
if (isCorrect(a) != isCorrect(b)) {
// a OR b is incorrect
} else {
// a AND b are correct or incorrect
}
Your test doesn't need boolean operators, just this:
if (isCorrect(a) == isCorrect(b)) {
// they both have the same value
} else {
// they don't ...
}
EDIT - I deliberately didn't use the same comments to reflect that the primary purpose of the comment should be to describe the intent, and not the specific implementation. In this case the simplest statement of intent is that both a and b obtained the same result.
simply:
if (isCorrect(a) == isCorrect(b))
{
// a AND b are both correct or incorrect
} else {
// a OR b is incorrect
}
How about this?
if(isCorrect(a) != isCorrect(b))
{
//problem
}
else
{
//not a problem
}
You can use XOR also, but != works fine and is more readable if you are dealing with boolean values, IMO.
Related
I am using Talend to filter out some rows from an excel file and they don't allow block statements. Everything has to be simple logic or using the ternary operator. So the problem is that the code/logic I need will be used across every cell in the column, BUT some of the cells are null, some are Strings and the rest are Strings that represent integers.
My logic needs to be this:
Return true if and only if PlanName == null || PlanName == 0 but as you can tell, it will fail when it tries to run this on a cell that contains the null or the cell that contains a String that isn't a number.
Is it possible to have this logic in java without the try-catch or block statements? This is what I have right now:
input_row.PlanName == null || Integer.parseInt(input_row.PlanName) == 0
Thanks!
Edit: Basically, I just need to write logic that does this:
Return true if input_row.PlanName == null OR if input_row.PlanName == 0
This needs to be done without using block-statements or try-catches because I am using Talend. So I can only use logical operators like && and || and I can use ternary operators as well.
In your situation, i'll go for routines : reusable bunch of code, handy for this kind of rules that would be hard to implement without if/else etc.
You can create two Routines in Talend, with static methods that you would be able to use in a tMap or a tJavaRow.
First Routine to know if your plan is a numeric or not :
public static boolean isNumeric(String strNum) {
if (strNum == null) {
return false;
}
try {
double d = Double.parseDouble(strNum);
} catch (NumberFormatException nfe) {
return false;
}
return true;
}
Then another routine like :
public static boolean correctPlanName(String planName) {
if(Relational.ISNULL(planName)){
return false;
}
else{
if(!isNumeric(planName)){
return false;
}
else {
return true;
}
}
}
Then you call Routines.correctPlanName(input_row.planName) in tMap/tJavaRow.
It should do the trick.
You can use a regular expression to check if the String only contains digits, then check if num == 0.
input_row.PlanName == null || (input_row.PlanName != null && input_row.PlanName.matches("\\d+") && Integer.parseInt(input_row.PlanName) == 0)
Edit: Probably overkill but to cover other cases e.g. floating point types, numbers prefixed with +/-, you could also do:
input_row.PlanName != null && input_row.PlanName.matches("[-+]?\\d*\\.?\\d+") && Double.parseDouble(input_row.PlanName) == 0)
What I am trying to perform: I am trying to reduce the conditional operators, Since Sonar is giving a error for it
if (!parseBooleanFromString(response.getBuy().getHasEligibleAccounts()) &&
(!parseBooleanFromString(response.getSell().getHasEligibleAccounts()) &&
(!parseBooleanFromString(response.getExchange().getHasEligibleAccounts()) &&
(!parseBooleanFromString(response.getWorkplaceRetirement().getHasPlansEligibleForChangeContributions()) &&
(!parseBooleanFromString(response.getWorkplaceRetirement().getHasPlansEligibleForChangeInvestments())))))) {
//Success
} else {
//Failure
}
private boolean parseBooleanFromString(String mStr) {
return Boolean.parseBoolean(mStr);
}
What i have tried:
I am trying to put all the boolean values in a list and check
Is that the best way to do or is there a more efficient way
You can also move these conditions into different functions which internally calls other functions and returns single boolean result. This way there will only one function in above if condition which will internally evaluate and returns result.
Since you're checking if each statement is false, how about you keep a global integer in memory: private int product = 1;. Make a separate method where you calculate the product (replaces the string to boolean parser):
private void updateProduct(String mStr){
if (Boolean.parseBoolean(mStr)) //If true, condition should fail
product *= 0;
else
product *= 1;
}
In essence, you are not running 'if statement' but multiplying the boolean:
product = 1;
updateProduct(response.getBuy().getHasEligibleAccounts());
updateProduct(response.getSell().getHasEligibleAccounts());
//etc
if (product > 0){
//success
} else {
//failure
}
Explanation: If at any point a condition was true, the product will always be 0. The only instance where the product is > 0 is when all statements were false
Not sure what sonar complains about, but you have alot of redundant parenthesis and confusing negations. Using DeMorgans law, you can at least simplify to:
boolean b = parseBooleanFromString(response.getBuy().getHasEligibleAccounts())
|| parseBooleanFromString(response.getSell().getHasEligibleAccounts())
|| parseBooleanFromString(response.getExchange().getHasEligibleAccounts())
|| parseBooleanFromString(response.getWorkplaceRetirement().getHasPlansEligibleForChangeContributions())
|| parseBooleanFromString(
response.getWorkplaceRetirement().getHasPlansEligibleForChangeContributions());
if (!b) {
or if you perfer more java 8 syntax
Stream<Boolean> bools = Stream.of(parseBooleanFromString(response.getBuy().getHasEligibleAccounts()),
parseBooleanFromString(response.getSell().getHasEligibleAccounts()),
parseBooleanFromString(response.getExchange().getHasEligibleAccounts()),
parseBooleanFromString(response.getWorkplaceRetirement().getHasPlansEligibleForChangeContributions()),
parseBooleanFromString(response.getWorkplaceRetirement().getHasPlansEligibleForChangeContributions()));
boolean c = ! bools.anyMatch(e -> e);
if (!c) {
I would do something like this:
private boolean checkEligibility(LaunchPoints response) {
final String trueStr = "true";
if (trueStr.equals(response.getBuy().getHasEligibleAccounts())) return true;
if (trueStr.equals(response.getSell().getHasEligibleAccounts())) return true;
[...]
return false;
}
The idea is, skip the parsing boolean, just check for "true" and make your conditions more readable.
I am writing some java code to check multiple conditions by if-else. The code is working properly but it is hard to do unit test.
reads lines that contains keyword conditionOne, conditionTwo or other keywords. hasConditionOneEnabled and hasConditionTwoEnabled are boolean values.
My real code has more else if statements than the provide example.
Can anyone help? Or give me some hint how to make the code shorter then I can write unit test easier? Thanks
boolean a = false;
boolean b = false;
if(line.contains("conditionOne")){
if(hasConditionOneEnabled){
a = true;
}else{
b = true;
}
}else if (line.contains("conditionTwo")){
if(hasConditionTwoEnabled){
a = true;
}else{
b = true;
}
}else{
a = true;
b = true;
}
if(a && b){
// do something 1
}else if(!a && b){
// do something 2
}else if(a && !b){
// do something 3
}else{
//both false, do nothing
}
a and b cannot be both false after the set of if-else statements.
In the first two if's variable a will have the same value than the corresponding hasConditionXXEnabled and b will be set as the opposite. The default else will set both to true.
Consider the following code:
a = true;
b = true;
if(line.contains("conditionOne")){
a = hasConditionOneEnabled;
b = !a;
}
else if(line.contains("conditionTwo")){
a = hasConditionTwoEnabled;
b = !a;
}
if(a && b){
// do something 1
}
else if(b){
// do something 2
}
else{
// do something 3
}
// test it on different line String input and different int value returned...
int xxx(String line) {
if(line.contains("conditionOne")){
status = hasConditionOneEnabled?0:1;
} else if (line.contains("conditionTwo")){
status = hasConditionTwoEnabled?0:1;
} else{
status = -1;
}
return status;
}
// test it base on different status value..
switch (status) {
case 0: ...;
case 1: ...;
default: ...;
}
However, if your if-else pattern can be continuously repeat after some modification, you may just create different boolean funciton for it.
First of all both a and b can never be false, so your last else statement is redundant.
Your entire set of conditional statements can be reduced to an if - else if - else block. You don't need variables a and b since you are using them to do something else anyway. Besides vague variables names like a and b hinder readability.
Let me first show you the code and I'll walk you through it subsequently.
boolean lineContainsCond1 = line.contains("conditionOne");
boolean lineContainsCond2 = line.contains("conditionTwo");
boolean lineContainsNeitherCondition = !lineContainsCond1 && !lineContainsCond2;
boolean conditionsForSomething3 = (lineContainsCond1 && conditionOneEnabled) || (lineContainsCond2 && conditionTwoEnabled);
if(lineContainsNeitherCondition)
//do something 1 (Note: this is the same something 1 from your code)
else if(conditionsForSomething3)
//do something 3
else
//do something 2
lineContainsNeitherCondition is essentially both a and b being true in your code.
conditionsForSomething3 tantamounts to a!b.
If both lineContainsNeitherCondition and conditionsForSomething3 are false, we can derive the following conclusions:
Given lineContainsNeitherCondition is false, either lineContainsCond1 is true or lineContainsCond2 is true
Case 1 : lineContainsCond1 is true:
In this case, either conditionOneIsEnabled is true or conditionOneEnabled is false. If it were true, then conditionFOrSomething3 cannot be false, if it's false, then that leads to lineContainsCond && !conditionOneEnabled to be true which leads to b!a in the original code and thereby executes //something 2.
A similar argument can be made for Case 2 : lineContainsCond2 is true.
Why don't reduce the amount of if else statements in your code.
Try replacing the if else statements with private methods that return a boolean. Try to in cooperate the below methods or similar methods into your above code.
Having a look at mookito great for mocking and stubbing. If you have a big project with lots of Objects will save you hours maybe days.
private boolean doesLineContainCondition(String line, String searchPhrase) {
if(line.contains(searchPhrase) {
return true;
} else {
return false;
}
}
private boolean hasConditionBeenEnabled(boolean condition) {
if(condition) {
a = true;
}
else {
b= true;
}
}
This question already has answers here:
Avoiding NullPointerException in Java
(66 answers)
Closed 9 years ago.
What is the best way to avoid multiple if blocks which is used for null checks in Java?
The following is my sample code. Which one is the most optimized way?
if (address!=null} {
if (firstName!=null) {
if (lastName!=null) {
}
}
}
Use &&. && is logical and. && combines two values and returns a boolean which is true if and only if both of its operands are true
if(address!=null && firstName!=null && lastName!=null)
{
}
For instance
boolean b;
b = 3 > 2 && 5 < 7; // b is true
b = 2 > 3 && 5 < 7; // b is now false
if loop is a wrong word. You should say if statements As in you case you can use OR (||) or AND (&&)statement like this
if(address!=null && firstName!=null && lastName!=null)
{
}
Try AND(&&) if you want to pass all checks or intead of nested if statements and try OR(||) for non nested like else if or simply say if you want to pass anyone of your condition But
if all of these are Strings then you should try like this
"yourValue".equals(stringValue)This will skip the null check.
Use and operator (&&)
if(address!=null && firstName!=null && lastName!=null)
{
//DoSomething here
}
And I suggest you to see Short circuit evaluation
there are no if LOOPS
boolean complete = address != null && firstName != null && lastName != null;
if (complete)
{
}
What about:
public boolean notNulls(Object ... args) {
for(Object arg : args)
if (arg == null) return false;
return true;
}
Use:
if (notNulls(address, firstName, lastName)) {
// do something
}
As others point out, a logical and (&&) is probably the best way to consolidate your logic. An && operation will only evaluate to true if both sides evaluate to true.
if (address != null && firstName != null && lastName != null) {
// Whatever you want to do with that...
} else {
// Whatever you want to do with bad input
}
For the sake of diversity, you could also use a try-catch approach. In Java, a NullPointerException will be thrown if you try to call a method on a null value, which you can catch and handle.
try {
// Whatever you want to do with that...
} catch (NullPointerException npe) {
// Whatever you want to do with bad input
}
This approach can be helpful if you've got a really big set of inputs that might be null, although in general I wouldn't advocate it. (The problem with the second approach is that if you call some other method from the try part that triggers a NullPointerException, it will end up in the catch block here, even though it may be totally unrelated to these inputs - i.e. you could make it hard for yourself to spot a bug in a different part of your program.)
I'm trying to make a group of if statements, in which each if will print given some argument is true, but an else that will only print if none of the ifs were returned. I don't think an else if would work in this case.
I have some code (the colors are just as examples):
boolean any=false;
if(redStage==2)
{ any=true; System.out.print(redComplete); }
if(blueStage==2)
{ any=true; System.out.print(blueComplete); }
if(greenStage==2)
{ any=true; System.out.print(greenComplete); }
if(any==false)
System.out.print(noneComplete);
Is there anything I can do to eliminate the need for a separate boolean to check whether any of the if's arguments were true?
Edit:
(I just noticed what may be confusing. The code im using isn't actually using return. Instead, it is printing out the results, which means more than one thing can be returned.)
Since you need to processes the stages independently from one another, and more than one can be complete at the same time, your code is as good as it can be.
What follows is my answer to your original question:
You don't need the boolean. Your code is equivalent to:
if (redStage == 2) { return redComplete; }
if (blueStage == 2) { return blueComplete; }
if (greenStage == 2) { return greenComplete; }
return noneComplete;
This makes use of the fact that each if body contains an unconditional return. If this wasn't the case, you could phrase the construct like so:
if (redStage == 2) {
// redComplete
} else if (blueStage == 2) {
// blueComplete
} else if (greenStage == 2) {
// greenComplete
} else {
// noneComplete
}