2017-10-07 174 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 
    }