2017-01-08 3 views
3

У меня есть 2 boolean переменных, например:Как определить разные типы поведения с 2 булевыми?

boolean isWhite; 
boolean isTall; 

Так что я хочу, чтобы определить различное поведение для 4 возможных случаев ({(isWhite, isTall), (!isWhite, isTall), (isWhite, !isTall), (!isWhite, !isTall)}).

1) Есть ли более элегантный и практичный способ сделать это чем с использованием if/else каждый раз?

if(isWhite) { 
    if(isTall) { 
     // Case 1 
    } 
    else { 
     // Case 2 
} 
else { 
    if(isTall) { 
     // Case 3 
    } 
    else { 
     // Case 4 
} 

2) Будет ли это быть любой разницы делать что-то вроде этого, а?

if (isWhite && isTall) 
    // Case 1 
if (isWhite && !isTall) 
    // Case 2 
if (!isWhite && isTall) 
    // Case 3 
if (!isWhite && !isTall) 
    // Case 4 
+2

Подсказка: рассмотрим ', если (isWhite && Установите фильтры и соберите)'. Если этот тест является «ложным», вы знаете, что либо 1) 'isWhite == false', 2)' isTall == false', либо 3) оба являются 'false'. Поэтому все, что вам нужно проверить, это '! IsWhite','! IsTall' и '! IsWhite &&! IsTall'. Дальше возможны такие вычеты; но может добавить к сложности. –

+0

Если поведение совершенно иное, я предпочел бы # 2, поскольку более глубокие углубления кажутся более трудными для чтения. Вы также можете использовать google для классов case/pattern в Scala, чтобы увидеть еще один доступный там – Ivan

+2

, если вы сделаете это, лучше используйте 'else-if' –

ответ

6

Ваше второе решение более читаемо. Но вместо if-statements следует использовать if-else. Рассмотрим, если первый случай уже является истинным. Остальные 3 выражения if будут вычисляться. Если вы используете инструкции if-else и первый случай истинен, остальные три оператора будут просто пропущены.

if (isWhite && isTall) {//case1} 
else if (isWhite && !isTall) {//case2} 
else if (!isWhite && isTall) {//case3} 
else {//case4} 
+0

Последний'! IsWhite' является избыточным. –

+0

да, ты прав :) –

4

Я бы предпочел первое, если/другое расположение, если вы не можете использовать enum Произнесите булевы были a и b

enum Combination { 
    A_B, NA_B, A_NB, NA_NB; 
} 

где NA_NB не А, не Б.

switch(comb) { 
    case A_B: 
     // 
     break; 
    // more cases 
    case NA_NB: 
     // 
     break; 
} 

Эта шкала немного лучше, если у вас больше логических значений, и она также может создавать комбинации, которые становятся более понятными.

Это позволяет полностью удалить блок if/else.

enum Combination implements Actionable { 
    A_B { 
     public void action(Arg arg) { 
      // something 
     } 
    }, 
    NA_B { 
     public void action(Arg arg) { 
      // something 
     } 
    }, 
    A_NB { 
     public void action(Arg arg) { 
      // something 
     } 
    }, 
    NA_NB { 
     public void action(Arg arg) { 
      // something 
     } 
    }; 
} 

Теперь вместо если/другое или переключатель, вы можете просто позвонить

actionable.action(something); 

Вы также можете легко добавить комбинации, возможно, пользовательские Actionable, которые не являются частью оригинальной библиотеки.

+0

Мне очень нравится Java, но это один из самых неприятных аспектов. Вы хотите избежать написания 8 строк 'if/else', поэтому в итоге вы создаете 30 строк кода шаблона. –

+0

Также, как бы вы инициализировали свою комбинацию? Это должно произойти откуда-то, поэтому вам, вероятно, все еще потребуется логическая логика, чтобы решить, используете ли вы 'NA_NB' или' A_B' –

+1

@ EricDulusil, это зависит от того, насколько сложна ваша ситуация. Когда вы начинаете с нескольких флагов, вы можете найти alter, что вы хотите, чтобы некоторые опции реорганизовали его, чтобы добавить некоторую структуру. –

2

Другой alternatve бы превратить их в int с (то есть 0 и 1) и использовать switch заявление, чтобы определить все возможные сценарии, например:

public static void main(String[] args) throws Exception{ 
    boolean white = true, tall = false; 

    StringBuilder result = new StringBuilder(); 
    result.append(white ? 1 : 0); 
    result.append(tall ? 1 : 0); 


    switch(result.toString()){ 
     case "00": 
      //do something 
      break; 

     case "01": 
      //do something 
      break; 

     case "10": 
      //do something 
      break; 

     case "11": 
      //do something 
      break; 
    } 

} 
+1

или вы можете сделать 'switch ((белый? 10: 0) + (хвост? 1: 0))' и сохранить создание каких-либо объектов. –

+2

Да, я использовал это только для удобства чтения. –

0

Еще одна возможность заключается в том, чтобы рассчитать caseNumber непосредственно из булевы:

int caseNumber = 1 + (isWhite ? 0 : 2) + (isTall ? 0 : 1); 

Вот example:

import java.util.*; 
import java.lang.*; 
import java.io.*; 

class Ideone 
{ 
    public static void main (String[] args) throws java.lang.Exception 
    { 
     System.out.println(getCaseNumber(true,true)); 
     System.out.println(getCaseNumber(true,false)); 
     System.out.println(getCaseNumber(false,true)); 
     System.out.println(getCaseNumber(false,false)); 
     switch(getCaseNumber(true,false)){ 
      case 1: 
       System.out.println("Case 1!"); 
       break; 
      case 2: 
       System.out.println("Case 2!"); 
       break; 
      case 3: 
       System.out.println("Case 3!"); 
       break; 
      case 4: 
       System.out.println("Case 4!"); 
       break;    
     } 
    } 

    private static int getCaseNumber(boolean bool1, boolean bool2) 
    { 
     return 1 + (bool1 ? 0 : 2) + (bool2 ? 0 : 1); 
    } 
} 

Он выводит:

1 
2 
3 
4 
Case 2! 

легче перебрать все возможности, он лучше масштабируется с п булевы и проще в использовании с switch заявления.

1 + как раз здесь, чтобы соответствовать вашему определению случая, в котором (true,true) is Case 1.

Вы можете удалить его, если хотите, caseNumber между 0 и 2**n-1.

+1

Можете ли вы прояснить цель «1 +»? –

0

Это часто просматриваемый образец, в котором свойства определяют разные случаи, по определенной бизнес-логике (основанной в реальном мире).

Такой контроль потока трудно проверить, проверить, отслеживать ошибки.

Лучший способ - сделать его более или менее декларативным списком. Может отдаленно что-то вроде:

{ false, false, (isWhite, isTall) -> { ... } }, 
{ false, true, (isWhite, isTall) -> { ... } }, 
{ true, false, (isWhite, isTall) -> { ... } }, 
{ true, true, (isWhite, isTall) -> { ... } }, 

(более читаемый использовать перечисления.)

Таким образом, вы можете создавать плагин (XML с корпусами), бревенчатыми лучше (именем класса обработчика). Особенно этот декларативный список может служить спецификацией бизнес-логики, читаемой клиентом. Поэтому было бы хорошо, если выбранному обработчику задана строка ID + версия, которая отображается пользователю в той или иной форме. Например, форма-версия в формате PDF.

Это означает изменение дизайна кода. Но помог мне, например, в случае многих подобных отчетов.

0

Как насчет этого? Как и в предыдущих ответах, но я использую else if для сокращения моего кода при обработке двух экземпляров, в которых логические значения не имеют одинакового значения.

if(isWhite && isTall){/**case 1*/} 
else if(isWhite){/**case 2*/}  // only need one boolean 
else if(isTall){/**case 3*/}   // on each of these lines 
else{/**case 4*/} 

Экономит немного набрав :)

Смежные вопросы