How to make an enum isXXX() method?

How would I insert isRED() and isBLACK() methods into this enum? I can't figure it out - even after googling for some time.. I don't know what value to access.

enum Suit {
   SPADES,
   HEARTS,
   DIAMONDS,
   CLUBS;
};

the main benefit of this for me is to simplify my calls.. (card.isRED()) is much shorter than (card == EnclosingClass.Suit.HEARTS || card == EnclosingClass.Suit.DIAMONDS);

and I have many such in my code

Jon Skeet
people
quotationmark

The simplest approach would probably be to have a boolean field indicating whether or not that suit was red. For example:

enum Suit {
   SPADES(false),
   HEARTS(true),
   DIAMONDS(true),
   CLUBS(false);

   private final boolean red;

   private Suit(boolean red) {
     this.red = red;
   }

   public boolean isRed() {
     return red;
   }
}

I would probably not add an isBlack method, instead relying on callers to use if (!foo.isRed()), but that's a separate matter. As noted in comments, if "red or black" aren't strictly opposites, or you anticipate them not being opposites in the future, you might want isBlack() - although in that case I'd at least start with an implementation which returned !isRed() and then changed it later for suits which were either both red and black or neither, as the need arose.

This feels right to me simply because the colour is essentially a piece of state about the value. While you obviously can determine it by checking against known-red suits, I tend to regard fields as the most natural way of expressing state. It's not like it's going to add much memory :)

Three alternatives:

1: Put the logic into the method itself:

enum Suit {
   SPADES,
   HEARTS,
   DIAMONDS,
   CLUBS;

   public boolean isRed() {
     return this == HEARTS || this == DIAMONDS;
   }
}

The downside of this solution is that it's error-prone when you add a new value - the compiler's not going to prompt you to look at the isRed method and consider whether or not you want to add another case there.

2: (Ugly) make it an abstract method that each suit overrides.

enum Suit {
   SPADES {
     @Override public boolean isRed() { return false; }
   },
   HEARTS,
     @Override public boolean isRed() { return true; }
   },
   DIAMONDS,
     @Override public boolean isRed() { return true; }
   },
   CLUBS {
     @Override public boolean isRed() { return false; }
   };

   public abstract boolean isRed();
}

3: Like 2, but give a "default" implementation returning one result, and only override it in the others.

Personally I'd go with the field, as per the first solution.

people

See more on this question at Stackoverflow