2016-10-10 4 views
1

У меня есть переменная, x.Наиболее сжатый способ выразить этот Java условный, не проверяя значение дважды

Я хочу назвать метод m()только в том случае, еслиx является одним из двух возможных значений.

При вызове m() я хочу передать ему аргумент, значение которого зависит от значения x.

Есть ли способ сделать это в Java без проверки значения x более чем один раз, и вызов/запись m() только в одном месте (т.е. не в нескольких ветвях if заявления)?

Одно из решений я развлекая:

switch (x) { 
    case 1: 
    y = "foo"; 
    break; 
    case 2: 
    y = "bar"; 
    break; 
    default: 
    y = null; 
    break; 
} 

if (y != null) m(y); 

Но я не могу помочь, но чувствую, что это технически проверки x дважды, просто скрывая этот факт, добавив «прокси» для повторной проверки.

(Чтобы уточнить, почему ограничения являются такими, какими они являются: при чтении кода у меня есть логика понимания времени, которая много разветвляется, когда существует высокая степень дублирования между ветвями - она ​​становится игрой «пятно разницы» «вместо того, чтобы просто видеть, что происходит. Я предпочитаю агрессивно реорганизовывать такое дублирование, что является привычкой, которая хорошо мне помогает в Ruby, JS и других языках, я надеюсь, что смогу научиться делать то же самое для Java и сделать код более легким для меня и других, чтобы понять с первого взгляда.)

+1

Создайте 'Map ', чтобы заполнить его значениями для' 1' и '2', а затем использовать' map.get (x) '- никаких проверок не требуется. –

+1

@ElliottFrisch Является ли Карта действительно лучшим решением, чем просто ломать его логику в двух разных выражениях 'if'? Если это произойдет много, я бы понял, но для небольшого количества этого случая ваше решение действительно интересно? – MadJlzz

+2

Ваш первый пример не работает вообще, он будет иметь тот же результат для 1 и 2. –

ответ

1

Использования «Готы» или эквивалента:

void do_m_if_appropriate() { 

    // x and y are assumed to be eg. member variables 

    switch (x) { 

    case 1: 
     y = "foo"; 
     break; 

    case 2: 
     y = "bar"; 
     break; 

    default: 
     return; // this is the "goto equivalent" part 
    } 

    m(y); 
} 

Выше довольно элегантные , В случае необходимости также можно изменить его, чтобы вернуть true или false в зависимости от того, называется ли он m() или просто y или null.


Вы также можете делать трюки с конструкциями циклов, хотя некоторые могут сказать, что это злоупотребление конструкции петли, и вы должны прокомментировать его соответствующим образом:

do { // note: not a real loop, used to skip call to m() 
    switch (x) { 

    case 1: 
     y = "foo"; 
     break; 

    case 2: 
     y = "bar"; 
     break; 

    default: 
     continue; // "goto equivalent" part 
    } 

    m(y); 
} while(false); 
+0

Ооо, мило. Вы используете окружающий объем как инструмент управления потоками, а затем используете продолжение блока, чтобы подразумевалось, что «найдено соответствующее значение». – henrebotha

+0

Принимая этот ответ на данный момент, поскольку он наименее странный, используя только инструменты, которые существуют на большинстве распространенных языков, в то же время удовлетворяя всем требованиям. – henrebotha

-1

Почему не

switch (x) { 
    case 1: 
    y = "foo"; 
    m(y); 
    break; 
    case 2: 
    y = "bar"; 
    m(y); 
    break; 
} 
+0

Как я уже говорил в сообщении: Я не хочу называть 'm()' более чем в одном месте, как вы это делали. – henrebotha

+0

Мой плохой, я думал, что вы имели в виду, что вы только хотели называть его один раз (не обязательно иметь одно место в коде). – Crazycolorz5

+0

Я отредактирую свой пост, чтобы сделать это более понятным. :) – henrebotha

3

Я не уверен, что вы хотите сделать, но вы можете возможно использовать карту, чтобы получить «у» параметра из «х»

Map<Integer, String> map = new HashMap<>(); 
map.put(1, "foo"); 
map.put(2, "bar"); 

if (map.containsKey(x)) { 
    m(map.get(x)); 
} 
+0

Разработчик Ruby во мне любит это. – henrebotha

+0

Рад видеть, как это;) Карты иногда могут быть очень эффективными для решения проблем. – Jos

+2

@Jos Я бы не назвал это эффективным любым способом ... Кратким или кратким, конечно, возможно, даже элегантным, но не эффективным. – hyde

1

Вот решение с OPTIONALS (мой Java синтаксис может быть немного неправильным). Обратите внимание, что для вас код выглядит так, но реализация мудрая, это похоже на приведенный вами пример (т. Е. Проверяет, является ли y исключительным значением).

switch (x) { 
    case 1: 
    y = Optional<String>.of("foo"); 
    break; 
    case 2: 
    y = Optional<String>.of("bar"); 
    break; 
    default: 
    y = Optional<String>.empty(); 
    break; 
} 
y.map((m's class)::m); 
result = y.orElse(<value result should take if x was invalid>); 

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