Подтвердить что ты не робот

Есть ли способ для побитовых-ИЛИ перечислений в Java?

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

enum Mood {
    HAPPY, SAD, CALM, SLEEPY, OPTIMISTIC, PENSIVE, ENERGETIC;
}

Есть ли способ сделать это:

if (currentMood == (HAPPY | OPTIMISTIC | ENERGETIC) {}

Вместо этого:

if (currentMood == HAPPY || currentMood == OPTIMISTIC || currentMood == ENERGETIC) {}

Или было бы лучше придерживаться целых чисел и флагов в этом случае?

4b9b3361

Ответ 1

Возможно, используйте что-то вроде EnumSet?

if (EnumSet<Mood>.of(HAPPY, OPTIMISTIC, ENERGETIC).contains(currentMood))
{ 
 //Do stuff...
}

Ответ 2

Дайте вашим перечислениям атрибут int.

enum Mood {
    private int id;

    HAPPY(1), SAD(2), CALM(4), SLEEPY(8), OPTIMISTIC(16), PENSIVE(32), ENERGETIC(64);

    Mood( int id ) {
        this.id = id;
    }
}

В случае if, тест против этого атрибута.

if ( currentMood & ( HAPPY.id | OPTIMISTIC.id | ENERGETIC.id ) != 0 ) { ... }

Ответ 3

Да

switch(currentmood){
    case HAPPY:
    case OPTIMISTIC:...
        Then do this
        break;
    default://else
}

Ответ 4

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

enum Mood {
     HAPPY, SAD...

     public boolean isRatherPositive() {
       ....
     }

}

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

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

Ответ 5

Вы можете указать свой enum логический флаг и протестировать его.

enum Mood {
    HAPPY(true), SAD, CALM, SLEEPY, OPTIMISTIC(true), PENSIVE, ENERGETIC(true);
    final boolean good;

    Mood(){this(false);}

    Mood(boolean isgood){this.good = isgood;}

    public isGood(){return good;}
}

Таким образом, проверка короткая

if (currentMood.isGood()) {}

Ответ 6

Другая опция:

public enum PaymentResponse {
    PP_SUCCESS, PP_FAILURE, CC_SUCCESS, CC_FAILURE;

    public boolean isSuccessful() {
            return ordinal() == CC_SUCCESS.ordinal()  ||  
                   ordinal() == PP_SUCCESS.ordinal() ;
    }
}

Ответ 7

Когда вы используете || вы должны указать оба значения, которые вы сравниваете каждый раз. Вы могли бы легко написать небольшой метод для этого.

if (currentMood.hasMood(HAPPY, OPTIMISTIC, ENERGETIC)) {}

public boolean hasMood(Mood ....)

Ответ 8

Один из подходов состоит в том, чтобы иметь EnumSet/switch/if и т.д. Это имеет смысл, если вы классифицируете перечисление каким-то образом, не являющимся частью самого перечисления. Например, является ли цвет частью цвета национального флага. "Модель зависимости" - это то, что национальный флаг зависит от цвета, но Цвет не заботится о существовании национальных флагов.

С другой стороны, если вы пытаетесь определить, является ли цвет основным цветом или нет (присущим человеческой модели цвета), то он принадлежит самому классу enum. Таким образом,

enum Color {
  private final boolean _crtPrimary;

  Red(true), Green(true), Blue(true), Black(false)

  Color(boolean crtPrimary) {
    _crtPrimary = crtPrimary;
  }

  public boolean isCRTPrimary() {
    return _crtPrimary;
  }
}

Ответ 9

Вы можете использовать YourEnum.values ​​()

Например, у меня есть класс с именем Enumerations. В нем у меня несколько классов Enum.

Например:

public class Enumerations {

public enum smtg
{
    Fast(1),
    Slow(2);

    private int number;
    private smtg(final int num) { number = num; }
    public int getsmtg()
    {
        return number;
    }
}
......

}

Когда я хочу использовать побитовое, я просто использую его так:

Enumerations.smtg.values()[Enumerations.smtg.Slow.ordinal() | Enumerations.smtg.Fast.ordinal()]