I got a review comment from my peers that i need to reduce the use of multiple If-else blocks in my code and instead use imperative programming techniques to achieve the same functionality
Background I have a List of Events and i need to return an event object based on few conditions.For an SOP Event and SOP Acknowledge Event the size of the list could be 2 or 3, for a Non-Sop Acknowledge event the size is 2 but event type is different, finally there is a single event where the size is 1.
//All Required Predicates
//SOP Special Event
if(eventList.size() >1 && results.getAcknowledgeUid().isEmpty()){
event = eventList.stream().filter(isOriginalEvent.and(isSOPEvent).and(isSOPSpecialEvent))
.findFirst().orElse(null);
}
else if (eventList.size() >1 && !results.getAcknowledgeUid().isEmpty()) {
// SOP Acnknowledge Event
if("SOP".equalsIgnoreCase(eventList.get(0).getEventType())) {
event = eventList.stream().filter(isAcknowledgeEvent)
.findFirst().orElse(null);
}
// Non SOP Acnknowledge Event
List<event> eventAcnknowledgeList = repository.findEventByUid(results.getAcnknowledgeUid);
event = eventAcnknowledgeList.stream().filter(isAcnknowledgeEvent)
.findFirst().orElse(null);
}
// Single Event
else if (eventList.size() >0) {
event = eventList.stream().filter(isOriginalEvent).findFirst().orElse(null);
}
I moved all my conditions within in the if else blocks to predicates and it's looking compact right now. But i'm still unable to reduce the if-else chain. I considered using ternary operator to merge the second and third blocks, but the code is looking clumsy if i did that. i'm unable to do the following as well.
Predicate<List<Event>> isMoreThanTwoEvents = event -> eventList.size() > 1;
event = eventList.stream().filter(isAcknowledgeEvent.and(isSOPEvent).and(isMoreThanTwoEvents))
.findFirst().orElse(null);
which gives me an error in the IDE
Required type Predicate <? super Event> Provided Predicate <List>
At least that block is wrong:
// SOP Acnknowledge Event
if("SOP".equalsIgnoreCase(eventList.get(0).getEventType())) {
event = eventList.stream().filter(isAcknowledgeEvent)
.findFirst().orElse(null);
}
// Non SOP Acnknowledge Event
List<event> eventAcnknowledgeList = repository.findEventByUid(results.getAcnknowledgeUid);
event = eventAcnknowledgeList.stream().filter(isAcnknowledgeEvent)
.findFirst().orElse(null);
there is a (probably) missing else, isn't it?
// SOP Acnknowledge Event
if ("SOP".equalsIgnoreCase(eventList.get(0).getEventType())) {
event = eventList.stream().filter(isAcknowledgeEvent)
.findFirst().orElse(null);
} else {
// Non SOP Acnknowledge Event
List<event> eventAcnknowledgeList = repository.findEventByUid(results.getAcnknowledgeUid);
event = eventAcnknowledgeList.stream().filter(isAcnknowledgeEvent)
.findFirst().orElse(null);
}
The ifs are;
if (n>1 && cond)
else if (n>1 && !cond)
else if (n>0)
at least testing cond
twice is redundant. You may write it:
if (n>1)
if (cond)
else
else if (n>0)
and if n
is always 1, 2 or 3 then the last test may be removed:
if (n>1)
if (cond)
else
else
which gives:
if (eventList.size()>1) {
if (results.getAcknowledgeUid().isEmpty()) {
event = eventList.stream().filter(isOriginalEvent.and(isSOPEvent).and(isSOPSpecialEvent))
.findFirst().orElse(null);
} else {
// SOP Acnknowledge Event
if("SOP".equalsIgnoreCase(eventList.get(0).getEventType())) {
event = eventList.stream().filter(isAcknowledgeEvent)
.findFirst().orElse(null);
} else {
// Non SOP Acnknowledge Event
List<event> eventAcnknowledgeList = repository.findEventByUid(results.getAcnknowledgeUid);
event = eventAcnknowledgeList.stream().filter(isAcnknowledgeEvent)
.findFirst().orElse(null);
}
else {
event = eventList.stream().filter(isOriginalEvent).findFirst().orElse(null);
}
You may also factorize the calls to findFirst.orElse and filters:
Stream<SOMETYPE> s = null;
Predicate<SOMETYPE> f = null
if (eventList.size()>1) {
if (results.getAcknowledgeUid().isEmpty()) {
s = eventList.stream();
f = isOriginalEvent.and(isSOPEvent).and(isSOPSpecialEvent);
} else {
if("SOP".equalsIgnoreCase(eventList.get(0).getEventType())) {
s = eventList.stream()
} else {
s = repository.findEventByUid(results.getAcnknowledgeUid).stream()
}
f = filter(isAcnknowledgeEvent);
else {
s = eventList.stream();
f = isOriginalEvent;
}
event = s.filter(f).findFirst().orElse(null);