How to refactor if statement using De Morgans law java

792 Views Asked by At

So I have a very unreadable if statement and someone suggested me to look at De Morgans law and refactor it so it would be more clean and readable. I got the idea how to do it with simple and short statements but I really do not know how to refactor my code. Note that first two are objects! Thanks for your help!

if (!userTemplate.getFromAccount().equals(document.getDetails())
    && !userTemplate.getBenAccount().equals(document.getFromAccount())
    && !userTemplate.getDetails().equals(document.getBenAccount())
    && !userTemplate.getBenType().equals(document.getBenType())
    && !userTemplate.getAmount().equals(document.getCreditAmount()))
4

There are 4 best solutions below

5
VHS On

From Wikipedia, De Morgans law can be explained in simple terms as

not (A or B) = not A and not B;

not (A and B) = not A or not B

So your current if statement

if (!userTemplate.getFromAccount().equals(document.getDetails())
                    && !userTemplate.getBenAccount().equals(document.getFromAccount())
                    && !userTemplate.getDetails().equals(document.getBenAccount())
                    && !userTemplate.getBenType().equals(document.getBenType())
                    && !userTemplate.getAmount().equals(document.getCreditAmount()))

Can be refactored as

if (!(userTemplate.getFromAccount().equals(document.getDetails())
                    || userTemplate.getBenAccount().equals(document.getFromAccount())
                    || userTemplate.getDetails().equals(document.getBenAccount())
                    || userTemplate.getBenType().equals(document.getBenType())
                    || userTemplate.getAmount().equals(document.getCreditAmount())))
0
Robert Kock On

Maybe I'm missing something but your if-statement says !A*!B*!C*!D which equals !(A+B+C+D).

2
Bentaye On

It would also be a good idea to extract all these conditions into booleans, would make the if more readable too.

boolean fromAccountCondition = userTemplate.getFromAccount().equals(document.getDetails());
boolean benAccountcondition = userTemplate.getBenAccount().equals(document.getFromAccount());
boolean detailsCondition = userTemplate.getDetails().equals(document.getBenAccount());
boolean benTypeCondition = userTemplate.getBenType().equals(document.getBenType());
boolean amountCondition = userTemplate.getAmount().equals(document.getCreditAmount()))

Then

if (!(fromAccountCondition || benAccountcondition 
      || detailsCondition || benTypeCondition || amountCondition)) {
  ...
} 

NOTE: I would actually prefer to put the negation in the booleans themselves, ie:

boolean fromAccountCondition = !userTemplate.getFromAccount().equals(document.getDetails());
boolean benAccountcondition = !userTemplate.getBenAccount().equals(document.getFromAccount());
boolean detailsCondition = !userTemplate.getDetails().equals(document.getBenAccount());
boolean benTypeCondition = !userTemplate.getBenType().equals(document.getBenType());
boolean amountCondition = !userTemplate.getAmount().equals(document.getCreditAmount()))

Then

if (fromAccountCondition && benAccountcondition 
    && detailsCondition && benTypeCondition && amountCondition)) {
  ...
} 
0
Thomas Fritsch On

De Morgan's law says (written in Java language):

(!A && !B && !C && ...)  ==  !(A || B || C || ...)

Therefore you can rewrite your code (I shorten the lengthy expressions for clarity):

if (!A && !B && !C && !D && !E)

to

if (!(A || B || C || D || E))