如何将包含多个AND,OR的语句转换为switch语句?

时间:2017-10-07 14:45:13

标签: java boolean-expression

我有一段看起来像这样的代码:

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

上面的代码满足了我的要求,但是我想用交换机块之类的东西把它改成一些更易读的代码。我知道交换机是如何工作的,但我不知道如何隐藏我现有的代码。

为了便于阅读,以下是清理版本(APENBACTCSUS并且DPEN_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)
      )
)

5 个答案:

答案 0 :(得分:3)

  

以上代码符合我的要求,但我想将其更改为   一些更易读的代码,使用像switch block等。

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()方法检查与nStatus值相关联的cStatus值。

这是一个片段:

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 :(得分:1)

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

首先,您可以清楚地看到PAN始终是CURRENT_STATUS因此,您可以缩短第一个条件。

其次有几个双向发音,其中某些状态可以NEW_STATUS CURRENT_STATUSSUS。第二个条件很容易表达。

最后,有两个直接的单向条件(PEN_CAN - &gt; CAN - &gt; 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) { } )由最后一个条件表示。

将它们组合在一起:

   SELECT 
        TEventInfoid ,A.TTNum,
        CASE WHEN TModelid = 3822 THEN e.title ELSE x.name END,
        CASE WHEN TModelid = 3822 THEN e.start_time ELSE x.start_Time END,
        CASE WHEN TModelid = 3822 THEN e.[address] ELSE x.[address] END
    FROM    
       T_Ticktets A
       LEFT JOIN dbo.sns_event e ON e.id=A.TEventInfoid
       LEFT JOIN dbo.sns_exhibition x  WHERE x.id=A.TEventInfoid
     WHERE A.TTNum='100229143644'

答案 2 :(得分: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

答案 3 :(得分: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));
.........
)

答案 4 :(得分:0)

以下是我的最终代码,我认为它比早期版本更具可读性和清晰度:

  

String cStatus = getcStatus();
   String nStatus = getnStatus();

     

String transitionString = cStatus +&#34; _&#34; + 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
  }