如何将包含多个AND、OR的If语句转换为switch语句?
How do I convert If statement consisting multiple AND, OR into a switch statement?
我有一段代码看起来像这样:
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//
}
以上代码满足了我的要求,但我想使用 switch 块等将其更改为更易读的代码。我知道 switch 是如何工作的,但我不确定如何隐藏我现有的代码。
为了便于阅读,这里是一个清理版本(A
是 PEN
,B
是 ACT
,C
是 SUS
和 D
是 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)
)
)
Above code is fulfilling my requirements but I want to change it to
some more readable code using anything like switch block etc.
AND
和 OR
条件语句的混合不能用 单一 开关案例代替。
您可以使用嵌入式开关盒(外部处理 cStatus
和内部处理 nStatus
),但它实际上不会提供可读代码:
boolean isEnabled = true;
switch (cStatus) {
case PEN:
switch (nStatus) {
case ACT:
case SUS:
case PEN_CAN:
isEnabled = false;
}
break;
case ACT:
switch (cStatus) {
...
}
break;
}
但是您可以通过消除重复和将具有相同 cStatus
值的条件语句分组,例如,使您的代码更具可读性。
您还可以使用 List.contains()
方法检查与 cStatus
值关联的 nStatus
值。
这是一个片段:
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))
...
}
我建议你创建一个图表来清楚地理解所有条件的组合。
首先你可以清楚地看到PAN
总是CURRENT_STATUS
因此,你可以缩短第一个条件。
其次,有几种双向条件,其中某些状态可能是 NEW_STATUS
或 CURRENT_STATUS
。很容易用第二个条件表示。
最后,有2个直的单向条件(SUS
-> PEN_CAN
-> CAN
)由最后一个条件表示。
将它们组合在一起:
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) {
}
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));
.........
)
您的代码不需要 switch 语句。
您可以考虑使用 Set
这是一些代码:
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
下面是我的最终代码,我认为它比早期版本更具可读性和简洁性:
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
}
我有一段代码看起来像这样:
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//
}
以上代码满足了我的要求,但我想使用 switch 块等将其更改为更易读的代码。我知道 switch 是如何工作的,但我不确定如何隐藏我现有的代码。
为了便于阅读,这里是一个清理版本(A
是 PEN
,B
是 ACT
,C
是 SUS
和 D
是 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)
)
)
Above code is fulfilling my requirements but I want to change it to some more readable code using anything like switch block etc.
AND
和 OR
条件语句的混合不能用 单一 开关案例代替。
您可以使用嵌入式开关盒(外部处理 cStatus
和内部处理 nStatus
),但它实际上不会提供可读代码:
boolean isEnabled = true;
switch (cStatus) {
case PEN:
switch (nStatus) {
case ACT:
case SUS:
case PEN_CAN:
isEnabled = false;
}
break;
case ACT:
switch (cStatus) {
...
}
break;
}
但是您可以通过消除重复和将具有相同 cStatus
值的条件语句分组,例如,使您的代码更具可读性。
您还可以使用 List.contains()
方法检查与 cStatus
值关联的 nStatus
值。
这是一个片段:
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))
...
}
我建议你创建一个图表来清楚地理解所有条件的组合。
首先你可以清楚地看到PAN
总是CURRENT_STATUS
因此,你可以缩短第一个条件。
其次,有几种双向条件,其中某些状态可能是 NEW_STATUS
或 CURRENT_STATUS
。很容易用第二个条件表示。
最后,有2个直的单向条件(SUS
-> PEN_CAN
-> CAN
)由最后一个条件表示。
将它们组合在一起:
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) {
}
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));
.........
)
您的代码不需要 switch 语句。
您可以考虑使用 Set
这是一些代码:
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
下面是我的最终代码,我认为它比早期版本更具可读性和简洁性:
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
}