Reducing conditional operators efficiently - java

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.

Related

Is there a better way to write this if statements?

I started recently as a developer and I am still struggling a bit with the way I write my code.
Is there a better way to write this two if-statements? How would you write it and why?
Java code:
#Override
#Transactional
public void deleteItem(final ConfigurationType type, final long itemId, final boolean force) {
this.applicationNameUtils.throwOnInvalidApplication(type.getApplication());
final ConfigurationItemModel item =
this.configurationItemRepository.findByApplicationAndTopicAndId(type.getApplication(), type.getTopic(), itemId)
.orElseThrow(() -> new ResourceNotFoundException(itemId, "Configuration Item"));
if (Boolean.TRUE.equals(item.getContentModificationOnly()) && Boolean.FALSE.equals(force)) {
throw new ContentModificationOnlyException("Configuration Item cannot be deleted");
}
if ((Boolean.TRUE.equals(item.getContentModificationOnly()) || Boolean.FALSE.equals(item.getContentModificationOnly())) && Boolean.TRUE.equals(force)) {
this.assignmentService.deleteAssignmentsByItem(item);
this.configurationInstanceRepository.deleteByItem(item);
this.configurationItemRepository.deleteById(itemId);
}
}
I am not sure if I can somehow combine this two in a if-else.
It looks like you don't care about item.getContentModificationOnly() is true or false in the second if-statement since your code is (Boolean.TRUE.equals(item.getContentModificationOnly()) || Boolean.FALSE.equals(item.getContentModificationOnly()). So if your logic is right I suggest you code like this:
if (fore) {
this.assignmentService.deleteAssignmentsByItem(item);
this.configurationInstanceRepository.deleteByItem(item);
this.configurationItemRepository.deleteById(itemId);
} else if (Boolean.TRUE.equals(item.getContentModificationOnly()) {
throw new ContentModificationOnlyException("Configuration Item cannot be deleted");
}
First if condition
if (item.getContentModificationOnly() && !force) {
Second If condition
if ((item.getContentModificationOnly() || !item.getContentModificationOnly()) && force) {
The below code will always return true
(item.getContentModificationOnly() || !item.getContentModificationOnly())
so modify second if stmnt to just
if (force){
Depends on the return type item.getContentModificationOnly(). If it's Boolean, than the second statement can be reduced to
if(item.getContentModificationOnly() != null && force)
If the return type of item.getContentModificationOnly() is boolean, than the statement can be reduced to
if(force)
and the answer of #LiLittleCat above if correct.

Return boolean from method that calls an Int

As per instructions: Write a static method that takes one integer as a formal parameter and returns a Boolean value of True if the parameter value is even and False if the it odd. It would seem my method must call an int instead of a boolean. With that being said I don't know how to return a boolean from a method that calls an int. I've tried this but it doesn't work.
EDIT - Language is JAVA.
\nEDIT 2 - For anyone looking at this in the future, I originally meant to type private static int result. Not private static boolean result. That mistake ended up fixing my code.
}
private static boolean result(int userIn)
{
if (userIn % 2 == 0)
{
int yes = 1;
return true;
}
else
{
return false;
}
}
Your original question didn't actually specify programming language, and it's not clear why you think you need to "call an int".
However in most C-descendent languages, and keeping with the style of your code quote, the following should work
private static boolean result(int userIn)
{
return (userIn % 2) == 0;
}
The expression (userIn % 2) == 0 will evaluate to a boolean (or your language's representation of one).
It is a common anti-idiom for people learning to program to do something like:
if (some condition is true)
then
return TRUE
else
return FALSE
Most (modern) programming languages allow you to simply return the result of evaluating a boolean condition, or to assign it to a suitably typed variable.
Thus
boolean result = (myvariable >= 10)
has the same result as, but is much more readable than:
boolean result
if (myvariable >= 10)
result = TRUE
else
result = FALSE
This may be what the person who set the assignment is wanting you to learn from it.

Simplify multiple if-else statements for unit testing

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;
}
}

Do I have this written properly? .equals AND !.equals if statement

FIXED. To get the statement to evaluate the way I wanted it to I had to write it this way:
public static Boolean pushCard(String S1, String S2) {
Boolean result = false;
if ((S1.equals("fire") || S1.equals("wind") || S1.equals("water")))
if (!S2.equals("fire") && (!S2.equals("water") && (!S2.equals("fire"))))
result = true;
return result;
} //end push card method
I can not tell if this comparison is causing issues. I was using == instead of .equals but then I learned that it was the wrong way to write it. Thanks for the help!
public static Boolean pushCard(String S1, String S2) {
Boolean result = false;
if ((S1.equals("fire") || S1.equals("wind") || S1.equals("water")))
if (!S2.equals("fire") || (!S2.equals("water") || (!S2.equals("fire"))))
result = true;
return result;
} //end push card method
Syntactically, your code will compile just fine, and the way you use .equals() method to compare strings is correct. Your use of the ! operator is also correct.
There is no guarantee that your code will not have logical errors though.
The only problem I can see you have "fire" mentioned twice in your second if statement. Otherwise, any problems you might be having could be related to your logic being wrong, since your syntax is pretty much correct and your usage is proper.
It is unclear what you're asking. The second if will always be true. You probably need :
if ((S1.equals("fire") || S1.equals("wind") || S1.equals("water")))
if (!S2.equals("fire") && (!S2.equals("water") && (!S2.equals("wind"))))
result = true;
public static Boolean pushCard(String S1, String S2)
{
Boolean result = false;
if (S1.equals("fire") || S1.equals("wind") || S1.equals("water"))
{
(!S2.equals("fire") || !S2.equals("water"))
result = true;
}
return result;
}
/end push card method
you had an extra pair of brackets in the first if statement.
I believe an if statement needs brackets {} when the code inside it is larger than one line.
your second if statement can be altered to just !S2.equals("fire") || !S2.equals("water")

evaluate boolean values in Java

I am trying to evaluate the following from a string
boolean value = evaluate("false || true && true && false || true");
I need to get a boolean value of true for this one.
Any ideas on how to solve this problem in the most efficient way?
String value = ("false || true && true && false || true");
boolean result = false;
for (String conj : value.split("\\|\\|")) {
boolean b = true;
for (String litteral : conj.split("&&"))
b &= Boolean.parseBoolean(litteral.trim());
result |= b;
}
System.out.println(result); // prints true
If the only operators are && and ||, then I think this will work:
static boolean eval(String str) {
String s = str.replaceAll("\\s|\\|\\|false|false\\|\\|", "");
return !s.contains("false") || s.contains("||true");
}
For more complicated expressions, I found this library just for that.
Don't know how efficient it is though.
You'll need a small boolean expressions grammar. A bit of recursive parsing should do the trick.
If you don't know how to write such a parser, you may use JavaCC or something similar.
there are parsergenerators available for which you can define a grammar.
But if you only got || and && as operators and true and false as values you can easily do this by yourself, by implmenting a very simple finite state machine:
1.) Split the string into the tokens
2.) parse the left most value by using Boolean.parseBoolean(token) and safe it's value in some instance variable (your state)
3.) combine your instance variable with the next boolean token using the given operator
4.) Repeat step3 until you finished through the whole string
This seems to work although i havent thorougly tested it :)
public class BooleanFSParser {
private boolean parse(String data) {
String[] tokens=data.split("\\s");
boolean state=Boolean.parseBoolean(tokens[0]);
for (int i=1;i<(tokens.length / 2) + 1;i=i+2){
if (tokens[i].equals("&&")){
state=state && Boolean.parseBoolean(tokens[i+1]);
}else{
state=state || Boolean.parseBoolean(tokens[i+1]);
}
}
return state;
}
public static void main(String[] args) {
BooleanFSParser parser = new BooleanFSParser();
boolean val = parser.parse("true && true || false");
System.out.println(String.valueOf(val));
}
}
thats should give you a cirrectly parsed value, but it will get a bit more complex if you allow brackets for example ;)
have fun and check here for the theory
Finite-state_machine

Categories