2017-10-07 176 views
3

我有一段代码,它看起来是这样的:如何将包含多个AND,OR的If语句转换为switch语句?

 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// 
} 

上面的代码是满足我的要求,但我想用什么样开关块等将其更改为一些可读的代码我知道如何切换工作但我不确定如何隐藏我现有的代码。


只是为了可读性,这里是一个清理的版本(APENBACTCSUSDPEN_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) 
    ) 
) 
+4

你并不真的需要一个开关把它清理干净,你的if语句可以通过使用状态正确置于括号检查减少冗余清理。 – zgc7009

+2

你能逻辑地解释'boolean'表达式代表什么吗?更容易理解然后...你可以创建子表达式并将它们存储在'boolean'变量中,给它们**好的变量名**。然后你的'if'-expression将使用这些变量并且是可读的。您还可以在表达式中识别公共变量,并创建**嵌套** if if表达式。 – Zabuza

回答

3

上面的代码是满足我的要求,但我想更改为 一些更易读的代码使用任何开关块等

ANDOR的混合条件语句不能被替换为单个切换案例。
你可以使用嵌入式交换机的情况下(外处理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)) 
    ... 
} 
1

我建议你创建一个图表清楚地了解所有的条件的组合。

首先你可以清楚地看到PAN总是这样CURRENT_STATUS因此可以缩短第一个条件。

其次有几个双向标志,其中某些状态可能是NEW_STATUS或者CURRENT_STATUS。第二个条件很容易表达。

最后,有2个直接单向条件(SUSPEN_CANCAN)由最后一个条件表示。

相结合他们:

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) { 

} 
0
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)); 
......... 
) 
1

你并不需要一个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 
1

下面是我最后的代码,我觉得它比以前的版本更可读和清洁:

字符串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 
    }