Есть ли способ для побитового ИЛИ перечисления в Java? - PullRequest
26 голосов
/ 08 июня 2011

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

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

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

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

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

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

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

Ответы [ 9 ]

35 голосов
/ 08 июня 2011

Может быть использовать что-то вроде EnumSet ?

if (EnumSet<Mood>.of(HAPPY, OPTIMISTIC, ENERGETIC).contains(currentMood))
{ 
 //Do stuff...
}
14 голосов
/ 08 июня 2011

Дайте вашим перечислениям атрибут 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 ) { ... }
4 голосов
/ 08 июня 2011

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

enum Mood {
     HAPPY, SAD...

     public boolean isRatherPositive() {
       ....
     }

}

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

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

3 голосов
/ 08 июня 2011

Да

switch(currentmood){
    case HAPPY:
    case OPTIMISTIC:...
        Then do this
        break;
    default://else
}
1 голос
/ 23 февраля 2017

Вы можете использовать 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()]
1 голос
/ 08 июня 2011

Один из подходов - использовать 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;
  }
}
1 голос
/ 08 июня 2011

Вы можете присвоить вашему 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()) {}
0 голосов
/ 12 июля 2016

Другой вариант:

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

    public boolean isSuccessful() {
            return ordinal() == CC_SUCCESS.ordinal()  ||  
                   ordinal() == PP_SUCCESS.ordinal() ;
    }
}
0 голосов
/ 08 июня 2011

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

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

public boolean hasMood(Mood ....)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...