DigitalJoel

2011/04/05

Get the “Next” value in a Java Enum

Filed under: development, java — Tags: — digitaljoel @ 10:32 pm

Java Enums. An awesome addition to Java 1.5 so we could avoid using public static ints for that purpose. I’ve been using them for some time with success and never noticed one deficiency until now. You can get the ordinal of an enum value with the ordinal() method. That is basically the index in the order the values were declared. So, if your enum look something like this:

 public enum Planet { MERCURY, VENUS, EARTH, MARS, JUPITER, SATURN, URANUS, NEPTUNE }

In this case, MERCURY would have an ordinal of 0, then VENUS 1, and so forth. Now, what if you want to iterate through them? You can get all the values of an enumerated type as an array using the values() method. Cool, right? Well, what if I don’t want to iterate through them, but I want to simply progress from one to the next. It would be cool if math operators (like + and -) would let you go from one to the next, but that’s not the case. I had a need to go from one to the next, so I changed my enum by adding the following method.

 private enum Planet { MERCURY, VENUS, EARTH, MARS, JUPITER, SATURN, URANUS, NEPTUNE;
    public Planet getNext() {
      return this.ordinal() < Planet.values().length - 1
          ? Planet.values()[this.ordinal() + 1]
          : null;
    }
  }

Now, if I do Planet.MERCURY.getNext() I would get VENUS. This takes advantage of the ordinal of each entry (which you cannot assign in any other way than the order in which you declare the enum values) and the values method, indexing into the values array to get the next value. If you attempt to go off the end, it’ll return null. It would be simple to make it wrap instead if that makes sense for your case. It would also be trivial to take this and implement a “getPrevious” if you have a need to go in reverse.

Advertisements

9 Comments »

  1. For cyclic getNext (NEPTUNE.getNext() returns MERCURY):

    private enum Planet {
    MERCURY, VENUS, EARTH, MARS, JUPITER, SATURN, URANUS, NEPTUNE;
    public Planet getNext() {
    return values()[(ordinal()+1) % values().length];
    }
    }

    Comment by Mauretto — 2011/07/29 @ 7:04 am

    • A nice, simple addition if you want next to wrap. Thanks mauretto.

      Comment by digitaljoel — 2011/08/01 @ 1:27 pm

    • for getLast()

      return values()[(this.ordinal() + values().length – 1) % values().length];

      Comment by Dakoon — 2012/04/25 @ 4:58 pm

      • Maybe I’m missing something, but wouldn’t a simpler implementation of getLast() be:

        return values()[values().length – 1];

        Comment by nmfon — 2012/09/02 @ 2:51 am

      • Oh nevermind, I see where you’re coming from… last as in “previous”, not “ultimate” 🙂

        Comment by nmfon — 2012/09/02 @ 2:58 am

  2. Very elegant solution, just what I needed! Thanks

    Comment by Topiltzin Dominguez — 2011/08/18 @ 6:08 pm

  3. You, sir, are a gentleman, and a scholar. 🙂

    Comment by Joe Smith — 2013/05/15 @ 3:48 pm

  4. Good stuff. I never thought to use the array returned by .values() in any way other than the foreach iteration.

    Comment by AName — 2014/04/25 @ 5:52 pm

    • Glad you found it useful.

      Comment by digitaljoel — 2014/05/29 @ 4:17 pm


RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Blog at WordPress.com.