Reputation: 97
This isValid() method has up to 6 attributes that can be set in order to be validated. If a particular attribute isn't set, it doesn't need to be validated. The logic appears to be working just how I would like it to work. How can I reduce the boolean expression complexity of this method?
import java.util.ArrayList;
import java.util.List;
public class Valid {
private int foo;
private int bar;
private int foobar;
private String foofoo;
private String barbar;
private String foobarfoobar;
private int myfoo;
private int mybar;
private int myfoobar;
private String myfoofoo;
private List<String> mybarbarlist = new ArrayList<String>();
private String myfoobarfoobar;
private boolean validate;
public boolean isValid() {
validate = false;
if ((((foo > 0) && (foo == myfoo)) || (foo == 0))
&& (((bar > 0) && (bar == mybar)) || (bar == 0))
&& (((foobar > 0) && (foobar == myfoobar)) || (foobar == 0))
&& (((foofoo != null) && (foofoo.equals(myfoofoo))) || (foofoo == null))
&& (((barbar != null) && (mybarbarlist.contains(barbar))) || (barbar == null))
&& (((foobarfoobar != null) && (foobarfoobar
.equals(myfoobarfoobar))) || (foobarfoobar == null)))
validate = true;
return validate;
}
public static void main(String[] args) {
Valid valid = new Valid();
// valid.foo = 1;
// valid.bar = 1;
// valid.foobar = 1;
// valid.foofoo = "1";
// valid.barbar = "1";
// valid.foobarfoobar = "1";
// valid.myfoo = 1;
// valid.mybar = 1;
// valid.myfoobar = 1;
// valid.myfoofoo = "1";
// valid.mybarbarlist.add("1");
// valid.myfoobarfoobar = "1";
System.out.println(valid.isValid());
}
}
Upvotes: 3
Views: 6025
Reputation: 5610
I would recommend reading about boolean algebra and simplifying boolean expressions. There are multiple ways of doing it, whether it be Karnaugh maps or simply using algebraic laws.
You can check out this which will give you a basic insight of what it's about. In relation to your code, I would recommend jotting down a truth table, and working out the truth values for when your method returns true. From there grab your current equation and simplify it as much as possible
To also give you an example of how simplification works:
A XOR B = A & !B OR !A & B
The left hand side if the simplified expression of the right hand side
For a list of laws that will definitely help you, check out Boolean Algebra Laws
Upvotes: 2
Reputation: 5128
I would start by giving meaningful names to each sub-expression and assign the results to variables and then do an && check between the variables. This will greatly increase readability.
Also your conditions all seem to have the form
(X != null && X == value) || X == null
which can be simplified using short-circuit evaluation to just
X == null || X == value
since if X == null
evaluates true then it doesn't need to check the right side, or if X == null
evaluates false and it needs to check the right side you already know its not null so you don't need to check for null in the expression on the right side.
Combining the two you would get something like this:
public boolean isValid() {
validate = false;
boolean fooCond = (foo == 0) || (foo == myfoo);
boolean barCond = (bar == 0) || (bar == mybar);
boolean foobarCond = (foobar == 0) || (foobar == myfoobar);
boolean foofooCond = (foofoo == null) || foofoo.equals(myfoofoo);
boolean barbarCond = (barbar == null) || mybarbarlist.contains(barbar);
boolean foobarfoobarCond = (foobarfoobar == null) || foobarfoobar.equals(myfoobarfoobar);
if (fooCond
&& barCond
&& foobarCond
&& foofooCond;
&& barbarCond
&& foobarfoobarCond) {
validate = true;
}
return validate;
}
EDIT
This doesn't quite work for your expressions where you are checking
((foo > 0) && (foo == myfoo)) || (foo == 0)
since if foo < 0
it returns false. If you really meant
((foo > 0) && (foo == myfoo)) || (foo <= 0)
then this method works as written.
Upvotes: 4