user668660
user668660

Reputation:

Is there a way to bitwise-OR enums in Java?

I'm using a state machine, and the code's getting really verbose when testing against a large number of possible states.

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

Is there any way to do this:

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

Instead of this:

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

Or would it be better to stick with integers and flags in this case?

Upvotes: 35

Views: 23773

Answers (9)

Roy Doron
Roy Doron

Reputation: 595

You can use YourEnum.values()

For example, I have Class called Enumerations. In it, I have multiple Enum Classes.

For example:

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;
    }
}
......

}

When I want to use bitwise, I just use it like that:

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

Upvotes: 0

ejaenv
ejaenv

Reputation: 2387

Another option:

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

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

Upvotes: -1

leonbloy
leonbloy

Reputation: 75906

Apart from other answers: if that particular set of states has a semantically defined meaning in your application (rather independent of your particular method, specific to the Enum) , I'd recommend to included that test as a method in the same Enum class.

enum Mood {
     HAPPY, SAD...

     public boolean isRatherPositive() {
       ....
     }

}

(or a static method) to be implemented by any of the logic suggested by the other answers (I'd favour the EnumSet, which could be statically o lazily instantiated).

To have the method in the Enum is useful to avoid code duplication, but above all, to prevent bugs in case you add members to the Enum or modify it.

Upvotes: 5

Dilum Ranatunga
Dilum Ranatunga

Reputation: 13374

One approach is to have EnumSet/switch/if etc. This makes sense if you are classifying the enumeration in some way that is not intrinsically part of the enumeration itself. For example, whether a color is part of the national flag's color. The 'dependency model' is that national flag depends on Color, but Color doesn't care about the existence of national flags.

On the other hand, if you are trying to determine whether a color is a primary color or not (intrinsic to human model of color), then it belongs on the enum class itself. So,

enum Color {
  private final boolean _crtPrimary;

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

  Color(boolean crtPrimary) {
    _crtPrimary = crtPrimary;
  }

  public boolean isCRTPrimary() {
    return _crtPrimary;
  }
}

Upvotes: 1

josefx
josefx

Reputation: 15656

You could give your enum a boolean flag and test for that.

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

This way the check is short

if (currentMood.isGood()) {}

Upvotes: 1

Mario Marinato
Mario Marinato

Reputation: 4617

Give your enums an int attribute.

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

On the if, test against this atrribute.

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

Upvotes: 18

Stas Jaro
Stas Jaro

Reputation: 4885

Yes

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

Upvotes: 2

Hunter McMillen
Hunter McMillen

Reputation: 61512

When you use || you have to specify both values you are comparing each time. You could easily write a small method to do this though.

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

public boolean hasMood(Mood ....)

Upvotes: 0

Yet Another Geek
Yet Another Geek

Reputation: 4289

Maybe use something like EnumSet?

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

Upvotes: 49

Related Questions