Reputation: 2963
I have a piece of code which looks something like this:
String cStatus = getStatus_c();
String nStatus = getStatus_n();
if (!((cStatus.equals(PEN) && nStatus.equals(ACT))
|| (cStatus.equals(PEN) && nStatus.equals(SUS))
|| (cStatus.equals(PEN) && nStatus.equals(PEN_CAN))
|| (cStatus.equals(ACT) && nStatus.equals(SUS))
|| (cStatus.equals(ACT) && nStatus.equals(PEN_CAN))
|| (cStatus.equals(SUS) && nStatus.equals(ACT))
|| (cStatus.equals(SUS) && nStatus.equals(PEN_CAN))
|| (cStatus.equals(PEN_CAN) && nStatus.equals(ACT))
|| (cStatus.equals(PEN_CAN) && nStatus.equals(CAN))))
{
//Do someting//
}
Above code is fulfilling my requirements but I want to change it to some more readable code using anything like switch block etc. I know how switch works but I'm not sure how to covert my existing code.
Just for readability, here is a cleaned-up version (A
is PEN
, B
is ACT
, C
is SUS
and D
is PEN_CAN
):
if (! ( (cStat == A && nStat == B)
|| (cStat == A && nStat == C)
|| (cStat == A && nStat == D)
|| (cStat == B && nStat == C)
|| (cStat == B && nStat == D)
|| (cStat == C && nStat == B)
|| (cStat == C && nStat == D)
|| (cStat == D && nStat == B)
|| (cStat == D && nStat == D)
)
)
Upvotes: 2
Views: 149
Reputation: 131456
Above code is fulfilling my requirements but I want to change it to some more readable code using anything like switch block etc.
A mixing of AND
and OR
conditional statement cannot be replaced by a single switch case.
You could use embedded switch cases (an outer to handle cStatus
and an inner to handle nStatus
) but it will really not give a readable code :
boolean isEnabled = true;
switch (cStatus) {
case PEN:
switch (nStatus) {
case ACT:
case SUS:
case PEN_CAN:
isEnabled = false;
}
break;
case ACT:
switch (cStatus) {
...
}
break;
}
But you could make your code more readable by eliminating the duplication and by grouping conditional statements with the same cStatus
value for example.
You could also use the List.contains()
method to check the nStatus
value associated to the cStatus
value.
Here is a snippet :
List<String> nStatusValueForcStatutPen = Arrays.asList("ACT", "SUS", "PEN_CAN");
List<String> nStatusValueForcStatutAct = Arrays.asList("SUS", "PEN_CAN");
...
if (!((cStatus.equals(PEN) && nStatusValueForcStatutPen.contains(nStatus))
|| (cStatus.equals(ACT) && nStatusValueForcStatutAct.contains(nStatus))
...
}
Upvotes: 3
Reputation: 2963
Below is my final code and I think it's much more readable and clean than the earlier version:
String cStatus = getcStatus();
String nStatus = getnStatus();String transitionString = cStatus + "_" + nStatus;
switch (transitionString) {
case "PEN_ACT":
break;
case "PEN_SUS":
break;
case "PEN_PENCAN":
break;
case "ACT_SUS":
break;
case "ACT_PENCAN":
break;
case "SUS_ACT":
break;
case "SUS_PENCAN":
break;
case "PENCAN_AC":
break;
case "PENCAN_CAN":
break;
default: {
//DO SOMETHING
//In my case throwing an exception i.e. program will not continue further.
}
}
{
//DO SOMETHING ELSE
}
Upvotes: 0
Reputation: 101
StatusChange curCange = new StatusChange(CURRENT_STATUS, NEW_STATUS);
if(!ngChange.contains(curChange)){
......do something.....
}
//New codes
class StatusChange{
final Status cur;
final Status nw;
..override equals method......
}
Set<StatusChange> ngChange=new HashSet();
(
ngChange.add(new StatusChange(PEN,ACT));
ngChange.add(new StatusChange(ACT,PEN));
.........
)
Upvotes: 0
Reputation: 38320
The code you have does not require a switch statement.
You might consider using a Set
Here is some code:
public class Combination
{
private final String cStatus;
private final String nStatus;
public Combination(
final String cStatusValue,
final String nStatusValue)
{
cStatus = StringUtils.trimToEmpty(cStatusValue);
nStatus = StringUtils.trimToEmpty(nStatusValue);
}
public int hashCode()
{
final int returnValue;
returnValue = cStatus.hashCode() + nStatus.hashCode();
}
public boolean equals(final Object object)
{
... implement equals
}
}
... during setup
private Set<Combination> goodCombinationSet = new HashSet<Combination>();
... add all good combinations to the goodCombinationSet.
... when testing.
final Combination testCombination = new Combination(cStatus, nStatus);
if (goodCombinationSet.contains(testCombination))
... do something
Upvotes: 1
Reputation: 44456
I'd suggest you create a diagram to understand clearly the combination of all the conditions.
Firstly you can clearly see that PAN
is always the CURRENT_STATUS
thus, you can shorten the first condition.
Secondly there are several two-way ocnditions, where certain states could be both NEW_STATUS
either CURRENT_STATUS
. It's easy to be expressed by the second condition.
Lastly, there are 2 straight one-way conditions (SUS
-> PEN_CAN
-> CAN
) expressed by the last condition.
Combine them together:
boolean penCondition = CURRENT_STATUS.equals(PEN) &&
(NEW_STATUS.equals(SUS) || NEW_STATUS.equals(PEN_CAN) || NEW_STATUS.equals(ACT));
boolean twoWayCondition = CURRENT_STATUS.equals(ACT) && (NEW_STATUS.equals(SUS) && NEW_STATUS.equals(PEN_CAN)) ||
NEW_STATUS.equals(ACT) && (CURRENT_STATUS.equals(SUS) && CURRENT_STATUS.equals(PEN_CAN));
boolean oneWayCondition = (CURRENT_STATUS.equals(SUS) && NEW_STATUS.equals(PEN_CAN)) ||
(CURRENT_STATUS.equals(PEN_CAN) && NEW_STATUS.equals(CAN));
if !(penCondition || twoWayCondition || oneWayCondition) {
}
Upvotes: 1