Enum of directions with opposites [duplicate]

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP











up vote
10
down vote

favorite
1













This question already has an answer here:



  • How can I associate an Enum with its opposite value, as in cardinal directions (North - South, East - West, etc)?

    4 answers



I'm currently working on a Dungeon game project which is composed of multiples rooms connected to each other.



Depending on the room you're in you can go to rooms next to yours by picking directions (North, South, East, West).



I've represented the directions with an Enum class and I'm looking for a way to implements that North is the opposite of South, East for West (and so on ...) for the sake of creating the layout of all the rooms in the final form of the game.



Here is my Enum class :



public enum Direction 
NORTH,
EAST,
SOUTH,
WEST;

public Direction getOppositeDirection()
return Direction.values()[(this.ordinal()+2)%4];





The problem is that currently the method is not very safe, any change in the order of declarations in the direction will break the method, any suggestions on how to do this in a better way?










share|improve this question















marked as duplicate by Boann java
Users with the  java badge can single-handedly close java questions as duplicates and reopen them as needed.

StackExchange.ready(function()
if (StackExchange.options.isMobile) return;

$('.dupe-hammer-message-hover:not(.hover-bound)').each(function()
var $hover = $(this).addClass('hover-bound'),
$msg = $hover.siblings('.dupe-hammer-message');

$hover.hover(
function()
$hover.showInfoMessage('',
messageElement: $msg.clone().show(),
transient: false,
position: my: 'bottom left', at: 'top center', offsetTop: -7 ,
dismissable: false,
relativeToBody: true
);
,
function()
StackExchange.helpers.removeMessages();

);
);
);
yesterday


This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.


















    up vote
    10
    down vote

    favorite
    1













    This question already has an answer here:



    • How can I associate an Enum with its opposite value, as in cardinal directions (North - South, East - West, etc)?

      4 answers



    I'm currently working on a Dungeon game project which is composed of multiples rooms connected to each other.



    Depending on the room you're in you can go to rooms next to yours by picking directions (North, South, East, West).



    I've represented the directions with an Enum class and I'm looking for a way to implements that North is the opposite of South, East for West (and so on ...) for the sake of creating the layout of all the rooms in the final form of the game.



    Here is my Enum class :



    public enum Direction 
    NORTH,
    EAST,
    SOUTH,
    WEST;

    public Direction getOppositeDirection()
    return Direction.values()[(this.ordinal()+2)%4];





    The problem is that currently the method is not very safe, any change in the order of declarations in the direction will break the method, any suggestions on how to do this in a better way?










    share|improve this question















    marked as duplicate by Boann java
    Users with the  java badge can single-handedly close java questions as duplicates and reopen them as needed.

    StackExchange.ready(function()
    if (StackExchange.options.isMobile) return;

    $('.dupe-hammer-message-hover:not(.hover-bound)').each(function()
    var $hover = $(this).addClass('hover-bound'),
    $msg = $hover.siblings('.dupe-hammer-message');

    $hover.hover(
    function()
    $hover.showInfoMessage('',
    messageElement: $msg.clone().show(),
    transient: false,
    position: my: 'bottom left', at: 'top center', offsetTop: -7 ,
    dismissable: false,
    relativeToBody: true
    );
    ,
    function()
    StackExchange.helpers.removeMessages();

    );
    );
    );
    yesterday


    This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.
















      up vote
      10
      down vote

      favorite
      1









      up vote
      10
      down vote

      favorite
      1






      1






      This question already has an answer here:



      • How can I associate an Enum with its opposite value, as in cardinal directions (North - South, East - West, etc)?

        4 answers



      I'm currently working on a Dungeon game project which is composed of multiples rooms connected to each other.



      Depending on the room you're in you can go to rooms next to yours by picking directions (North, South, East, West).



      I've represented the directions with an Enum class and I'm looking for a way to implements that North is the opposite of South, East for West (and so on ...) for the sake of creating the layout of all the rooms in the final form of the game.



      Here is my Enum class :



      public enum Direction 
      NORTH,
      EAST,
      SOUTH,
      WEST;

      public Direction getOppositeDirection()
      return Direction.values()[(this.ordinal()+2)%4];





      The problem is that currently the method is not very safe, any change in the order of declarations in the direction will break the method, any suggestions on how to do this in a better way?










      share|improve this question
















      This question already has an answer here:



      • How can I associate an Enum with its opposite value, as in cardinal directions (North - South, East - West, etc)?

        4 answers



      I'm currently working on a Dungeon game project which is composed of multiples rooms connected to each other.



      Depending on the room you're in you can go to rooms next to yours by picking directions (North, South, East, West).



      I've represented the directions with an Enum class and I'm looking for a way to implements that North is the opposite of South, East for West (and so on ...) for the sake of creating the layout of all the rooms in the final form of the game.



      Here is my Enum class :



      public enum Direction 
      NORTH,
      EAST,
      SOUTH,
      WEST;

      public Direction getOppositeDirection()
      return Direction.values()[(this.ordinal()+2)%4];





      The problem is that currently the method is not very safe, any change in the order of declarations in the direction will break the method, any suggestions on how to do this in a better way?





      This question already has an answer here:



      • How can I associate an Enum with its opposite value, as in cardinal directions (North - South, East - West, etc)?

        4 answers







      java enums






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited yesterday









      Community♦

      11




      11










      asked yesterday









      Rémy.W

      887




      887




      marked as duplicate by Boann java
      Users with the  java badge can single-handedly close java questions as duplicates and reopen them as needed.

      StackExchange.ready(function()
      if (StackExchange.options.isMobile) return;

      $('.dupe-hammer-message-hover:not(.hover-bound)').each(function()
      var $hover = $(this).addClass('hover-bound'),
      $msg = $hover.siblings('.dupe-hammer-message');

      $hover.hover(
      function()
      $hover.showInfoMessage('',
      messageElement: $msg.clone().show(),
      transient: false,
      position: my: 'bottom left', at: 'top center', offsetTop: -7 ,
      dismissable: false,
      relativeToBody: true
      );
      ,
      function()
      StackExchange.helpers.removeMessages();

      );
      );
      );
      yesterday


      This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.






      marked as duplicate by Boann java
      Users with the  java badge can single-handedly close java questions as duplicates and reopen them as needed.

      StackExchange.ready(function()
      if (StackExchange.options.isMobile) return;

      $('.dupe-hammer-message-hover:not(.hover-bound)').each(function()
      var $hover = $(this).addClass('hover-bound'),
      $msg = $hover.siblings('.dupe-hammer-message');

      $hover.hover(
      function()
      $hover.showInfoMessage('',
      messageElement: $msg.clone().show(),
      transient: false,
      position: my: 'bottom left', at: 'top center', offsetTop: -7 ,
      dismissable: false,
      relativeToBody: true
      );
      ,
      function()
      StackExchange.helpers.removeMessages();

      );
      );
      );
      yesterday


      This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.
























          5 Answers
          5






          active

          oldest

          votes

















          up vote
          7
          down vote



          accepted










          You could make the method abstract, and implement it for each constant.



          enum Direction 
          NORTH()
          public Direction getOppositeDirection()
          return SOUTH;

          ,
          EAST()
          public Direction getOppositeDirection()
          return WEST;

          ,
          SOUTH()
          public Direction getOppositeDirection()
          return NORTH;

          ,
          WEST()
          public Direction getOppositeDirection()
          return EAST;

          ;

          public abstract Direction getOppositeDirection();



          It's a bit wordy, though.



          The next method is shorter but more difficult to read.



          enum Direction 
          NORTH, EAST, SOUTH, WEST;

          static
          (SOUTH.oppositeDirection = NORTH).oppositeDirection = SOUTH;
          (WEST.oppositeDirection = EAST).oppositeDirection = WEST;


          private Direction oppositeDirection;

          public Direction getOppositeDirection()
          return oppositeDirection;







          share|improve this answer


















          • 1




            What even is NORTH()? Is it a method? A field?
            – David Stockinger
            yesterday










          • NORTH is a constant instance of Direction; in order to be a valid one, it should provide an implementation for all the abstract methods declared
            – Andrew Tobilko
            yesterday










          • @DavidStockinger NORTH() ... is the way to determine a constructor to call and to provide/override methods. Here, it's the default constructor. If we had a Direction(String s) constructor, we could use NORTH("string") ... .
            – Andrew Tobilko
            yesterday






          • 1




            @AndrewTobilko this also adds an extra bonus, that if you wanted to add extra direction, like SOUTH-EAST - it would not compile without providing an opposite.
            – Eugene
            yesterday

















          up vote
          3
          down vote













          You may also want to look in lambda for other case, but you will need to use a little cheat code because NORTH and EAST can't reference constant/field before they are defined:



          import java.util.function.Supplier;

          public enum Direction
          NORTH,
          EAST,
          SOUTH,
          WEST;

          private Supplier<Direction> opposite;

          private Direction()


          static // initialize opposite field
          for (final Direction direction : Direction.values())
          direction.opposite = oppositeOf(direction);



          private static Supplier<Direction> oppositeOf(final Direction self)
          switch (self)
          case NORTH: return () -> SOUTH;
          case WEST: return () -> EAST;
          case EAST: return () -> WEST;
          case SOUTH: return () -> NORTH;
          default: throw new IllegalStateException("Invalid opposite: " + self);



          public final Direction getOppositeDirection()
          return opposite.get();


          public static void main(final String args)
          for (final Direction dir : Direction.values())
          System.out.println(dir + " is opposite of " + dir.getOppositeDirection());





          This does the same than having abstract method, but is more concise (except here because you need to add more to the code): you read directly what is the opposite direction instead of having the verbose method declaration (it is another matter if you need to also add other methods).



          Also, it will not create pseudo class for each enums constant (eg: Direction$1, Direction$2, ...) because there is no need to.






          share|improve this answer






















          • I thought about it, but it shouldn't compile because there are 2 illegal forward references here.
            – Andrew Tobilko
            yesterday










          • There are no forward reference: it would make an error if I was passing the field directly in the constructor, but that is not the case here. The lambda is not evaluated before getOppositeDirection get called.
            – NoDataFound
            yesterday










          • it doesn't compile for me
            – Andrew Tobilko
            yesterday










          • You were right. There was an error for NORTH/EAST. Fixed it in answer.
            – NoDataFound
            yesterday










          • Suppliers are redundant when you use a static initialisation block
            – Andrew Tobilko
            yesterday

















          up vote
          2
          down vote













          The concise answer is:



          public Direction getOppositeDirection() 
          return
          this==NORTH ? SOUTH :
          this==EAST ? WEST :
          this==SOUTH ? NORTH :
          EAST;



          You might prefer case statement



          public Direction getOppositeDirection() 
          switch (this)
          case NORTH: return SOUTH;
          case EAST: return WEST;
          case SOUTH: return NORTH;
          case WEST: return EAST;
          default: throw new Error();







          share|improve this answer



























            up vote
            1
            down vote













            Another option could be to use a Map (perhaps even an EnumMap), e.g.:



            public enum Direction 

            NORTH,
            EAST,
            SOUTH,
            WEST;

            private static final Map<Direction, Direction> OPPOSITES = ImmutableMap.of(
            NORTH, SOUTH,
            EAST, WEST,
            SOUTH, NORTH,
            WEST, EAST
            );

            public Direction oppositeDirection()
            return OPPOSITES.get(this);







            share|improve this answer




















            • I don't understand the downvote - this is the very first thing I thought about when reading the question, 1+
              – Eugene
              yesterday










            • There was this one too :) but you should provide a solution using EnumMap and not Guava.
              – NoDataFound
              yesterday


















            up vote
            0
            down vote













            I feel like the easiest way would be to do it the way you originally proposed, but accept a parameter in the constructor:



            public static enum Direction 
            NORTH(0),
            WEST(1),
            SOUTH(2),
            EAST(3);

            private int dir;

            private Direction(int dir)
            this.dir = dir;


            public static Direction getNewDirection(int dir)
            // ensure direction is in [0, 4)
            dir %= 4;
            if (dir < 0) dir += 4;
            for (Direction d : Direction.values())
            if (d.dir == dir) return d;

            throw new Error();


            public Direction getOppositeDirection()
            return getNewDirection(dir + 2);




            The advantages to this are numerous: directions essentially form a group of rotations, which correspond to the integers modulo 4. They have a natural representation as integers modulo 4. Now, if we want to get the direction that is clockwise, we can do that easily (getNewDirection(dir + 1)), or counterclockwise (getNewDirection(dir - 1)). If the character is facing direction d1 and we want to know which way to turn to face a new direction d2, this corresponds to subtraction, etc. All of the operations that you might want to do have a natural way to do it with the integers modulo 4.






            share|improve this answer



























              5 Answers
              5






              active

              oldest

              votes








              5 Answers
              5






              active

              oldest

              votes









              active

              oldest

              votes






              active

              oldest

              votes








              up vote
              7
              down vote



              accepted










              You could make the method abstract, and implement it for each constant.



              enum Direction 
              NORTH()
              public Direction getOppositeDirection()
              return SOUTH;

              ,
              EAST()
              public Direction getOppositeDirection()
              return WEST;

              ,
              SOUTH()
              public Direction getOppositeDirection()
              return NORTH;

              ,
              WEST()
              public Direction getOppositeDirection()
              return EAST;

              ;

              public abstract Direction getOppositeDirection();



              It's a bit wordy, though.



              The next method is shorter but more difficult to read.



              enum Direction 
              NORTH, EAST, SOUTH, WEST;

              static
              (SOUTH.oppositeDirection = NORTH).oppositeDirection = SOUTH;
              (WEST.oppositeDirection = EAST).oppositeDirection = WEST;


              private Direction oppositeDirection;

              public Direction getOppositeDirection()
              return oppositeDirection;







              share|improve this answer


















              • 1




                What even is NORTH()? Is it a method? A field?
                – David Stockinger
                yesterday










              • NORTH is a constant instance of Direction; in order to be a valid one, it should provide an implementation for all the abstract methods declared
                – Andrew Tobilko
                yesterday










              • @DavidStockinger NORTH() ... is the way to determine a constructor to call and to provide/override methods. Here, it's the default constructor. If we had a Direction(String s) constructor, we could use NORTH("string") ... .
                – Andrew Tobilko
                yesterday






              • 1




                @AndrewTobilko this also adds an extra bonus, that if you wanted to add extra direction, like SOUTH-EAST - it would not compile without providing an opposite.
                – Eugene
                yesterday














              up vote
              7
              down vote



              accepted










              You could make the method abstract, and implement it for each constant.



              enum Direction 
              NORTH()
              public Direction getOppositeDirection()
              return SOUTH;

              ,
              EAST()
              public Direction getOppositeDirection()
              return WEST;

              ,
              SOUTH()
              public Direction getOppositeDirection()
              return NORTH;

              ,
              WEST()
              public Direction getOppositeDirection()
              return EAST;

              ;

              public abstract Direction getOppositeDirection();



              It's a bit wordy, though.



              The next method is shorter but more difficult to read.



              enum Direction 
              NORTH, EAST, SOUTH, WEST;

              static
              (SOUTH.oppositeDirection = NORTH).oppositeDirection = SOUTH;
              (WEST.oppositeDirection = EAST).oppositeDirection = WEST;


              private Direction oppositeDirection;

              public Direction getOppositeDirection()
              return oppositeDirection;







              share|improve this answer


















              • 1




                What even is NORTH()? Is it a method? A field?
                – David Stockinger
                yesterday










              • NORTH is a constant instance of Direction; in order to be a valid one, it should provide an implementation for all the abstract methods declared
                – Andrew Tobilko
                yesterday










              • @DavidStockinger NORTH() ... is the way to determine a constructor to call and to provide/override methods. Here, it's the default constructor. If we had a Direction(String s) constructor, we could use NORTH("string") ... .
                – Andrew Tobilko
                yesterday






              • 1




                @AndrewTobilko this also adds an extra bonus, that if you wanted to add extra direction, like SOUTH-EAST - it would not compile without providing an opposite.
                – Eugene
                yesterday












              up vote
              7
              down vote



              accepted







              up vote
              7
              down vote



              accepted






              You could make the method abstract, and implement it for each constant.



              enum Direction 
              NORTH()
              public Direction getOppositeDirection()
              return SOUTH;

              ,
              EAST()
              public Direction getOppositeDirection()
              return WEST;

              ,
              SOUTH()
              public Direction getOppositeDirection()
              return NORTH;

              ,
              WEST()
              public Direction getOppositeDirection()
              return EAST;

              ;

              public abstract Direction getOppositeDirection();



              It's a bit wordy, though.



              The next method is shorter but more difficult to read.



              enum Direction 
              NORTH, EAST, SOUTH, WEST;

              static
              (SOUTH.oppositeDirection = NORTH).oppositeDirection = SOUTH;
              (WEST.oppositeDirection = EAST).oppositeDirection = WEST;


              private Direction oppositeDirection;

              public Direction getOppositeDirection()
              return oppositeDirection;







              share|improve this answer














              You could make the method abstract, and implement it for each constant.



              enum Direction 
              NORTH()
              public Direction getOppositeDirection()
              return SOUTH;

              ,
              EAST()
              public Direction getOppositeDirection()
              return WEST;

              ,
              SOUTH()
              public Direction getOppositeDirection()
              return NORTH;

              ,
              WEST()
              public Direction getOppositeDirection()
              return EAST;

              ;

              public abstract Direction getOppositeDirection();



              It's a bit wordy, though.



              The next method is shorter but more difficult to read.



              enum Direction 
              NORTH, EAST, SOUTH, WEST;

              static
              (SOUTH.oppositeDirection = NORTH).oppositeDirection = SOUTH;
              (WEST.oppositeDirection = EAST).oppositeDirection = WEST;


              private Direction oppositeDirection;

              public Direction getOppositeDirection()
              return oppositeDirection;








              share|improve this answer














              share|improve this answer



              share|improve this answer








              edited yesterday

























              answered yesterday









              Andrew Tobilko

              22.4k83877




              22.4k83877







              • 1




                What even is NORTH()? Is it a method? A field?
                – David Stockinger
                yesterday










              • NORTH is a constant instance of Direction; in order to be a valid one, it should provide an implementation for all the abstract methods declared
                – Andrew Tobilko
                yesterday










              • @DavidStockinger NORTH() ... is the way to determine a constructor to call and to provide/override methods. Here, it's the default constructor. If we had a Direction(String s) constructor, we could use NORTH("string") ... .
                – Andrew Tobilko
                yesterday






              • 1




                @AndrewTobilko this also adds an extra bonus, that if you wanted to add extra direction, like SOUTH-EAST - it would not compile without providing an opposite.
                – Eugene
                yesterday












              • 1




                What even is NORTH()? Is it a method? A field?
                – David Stockinger
                yesterday










              • NORTH is a constant instance of Direction; in order to be a valid one, it should provide an implementation for all the abstract methods declared
                – Andrew Tobilko
                yesterday










              • @DavidStockinger NORTH() ... is the way to determine a constructor to call and to provide/override methods. Here, it's the default constructor. If we had a Direction(String s) constructor, we could use NORTH("string") ... .
                – Andrew Tobilko
                yesterday






              • 1




                @AndrewTobilko this also adds an extra bonus, that if you wanted to add extra direction, like SOUTH-EAST - it would not compile without providing an opposite.
                – Eugene
                yesterday







              1




              1




              What even is NORTH()? Is it a method? A field?
              – David Stockinger
              yesterday




              What even is NORTH()? Is it a method? A field?
              – David Stockinger
              yesterday












              NORTH is a constant instance of Direction; in order to be a valid one, it should provide an implementation for all the abstract methods declared
              – Andrew Tobilko
              yesterday




              NORTH is a constant instance of Direction; in order to be a valid one, it should provide an implementation for all the abstract methods declared
              – Andrew Tobilko
              yesterday












              @DavidStockinger NORTH() ... is the way to determine a constructor to call and to provide/override methods. Here, it's the default constructor. If we had a Direction(String s) constructor, we could use NORTH("string") ... .
              – Andrew Tobilko
              yesterday




              @DavidStockinger NORTH() ... is the way to determine a constructor to call and to provide/override methods. Here, it's the default constructor. If we had a Direction(String s) constructor, we could use NORTH("string") ... .
              – Andrew Tobilko
              yesterday




              1




              1




              @AndrewTobilko this also adds an extra bonus, that if you wanted to add extra direction, like SOUTH-EAST - it would not compile without providing an opposite.
              – Eugene
              yesterday




              @AndrewTobilko this also adds an extra bonus, that if you wanted to add extra direction, like SOUTH-EAST - it would not compile without providing an opposite.
              – Eugene
              yesterday












              up vote
              3
              down vote













              You may also want to look in lambda for other case, but you will need to use a little cheat code because NORTH and EAST can't reference constant/field before they are defined:



              import java.util.function.Supplier;

              public enum Direction
              NORTH,
              EAST,
              SOUTH,
              WEST;

              private Supplier<Direction> opposite;

              private Direction()


              static // initialize opposite field
              for (final Direction direction : Direction.values())
              direction.opposite = oppositeOf(direction);



              private static Supplier<Direction> oppositeOf(final Direction self)
              switch (self)
              case NORTH: return () -> SOUTH;
              case WEST: return () -> EAST;
              case EAST: return () -> WEST;
              case SOUTH: return () -> NORTH;
              default: throw new IllegalStateException("Invalid opposite: " + self);



              public final Direction getOppositeDirection()
              return opposite.get();


              public static void main(final String args)
              for (final Direction dir : Direction.values())
              System.out.println(dir + " is opposite of " + dir.getOppositeDirection());





              This does the same than having abstract method, but is more concise (except here because you need to add more to the code): you read directly what is the opposite direction instead of having the verbose method declaration (it is another matter if you need to also add other methods).



              Also, it will not create pseudo class for each enums constant (eg: Direction$1, Direction$2, ...) because there is no need to.






              share|improve this answer






















              • I thought about it, but it shouldn't compile because there are 2 illegal forward references here.
                – Andrew Tobilko
                yesterday










              • There are no forward reference: it would make an error if I was passing the field directly in the constructor, but that is not the case here. The lambda is not evaluated before getOppositeDirection get called.
                – NoDataFound
                yesterday










              • it doesn't compile for me
                – Andrew Tobilko
                yesterday










              • You were right. There was an error for NORTH/EAST. Fixed it in answer.
                – NoDataFound
                yesterday










              • Suppliers are redundant when you use a static initialisation block
                – Andrew Tobilko
                yesterday














              up vote
              3
              down vote













              You may also want to look in lambda for other case, but you will need to use a little cheat code because NORTH and EAST can't reference constant/field before they are defined:



              import java.util.function.Supplier;

              public enum Direction
              NORTH,
              EAST,
              SOUTH,
              WEST;

              private Supplier<Direction> opposite;

              private Direction()


              static // initialize opposite field
              for (final Direction direction : Direction.values())
              direction.opposite = oppositeOf(direction);



              private static Supplier<Direction> oppositeOf(final Direction self)
              switch (self)
              case NORTH: return () -> SOUTH;
              case WEST: return () -> EAST;
              case EAST: return () -> WEST;
              case SOUTH: return () -> NORTH;
              default: throw new IllegalStateException("Invalid opposite: " + self);



              public final Direction getOppositeDirection()
              return opposite.get();


              public static void main(final String args)
              for (final Direction dir : Direction.values())
              System.out.println(dir + " is opposite of " + dir.getOppositeDirection());





              This does the same than having abstract method, but is more concise (except here because you need to add more to the code): you read directly what is the opposite direction instead of having the verbose method declaration (it is another matter if you need to also add other methods).



              Also, it will not create pseudo class for each enums constant (eg: Direction$1, Direction$2, ...) because there is no need to.






              share|improve this answer






















              • I thought about it, but it shouldn't compile because there are 2 illegal forward references here.
                – Andrew Tobilko
                yesterday










              • There are no forward reference: it would make an error if I was passing the field directly in the constructor, but that is not the case here. The lambda is not evaluated before getOppositeDirection get called.
                – NoDataFound
                yesterday










              • it doesn't compile for me
                – Andrew Tobilko
                yesterday










              • You were right. There was an error for NORTH/EAST. Fixed it in answer.
                – NoDataFound
                yesterday










              • Suppliers are redundant when you use a static initialisation block
                – Andrew Tobilko
                yesterday












              up vote
              3
              down vote










              up vote
              3
              down vote









              You may also want to look in lambda for other case, but you will need to use a little cheat code because NORTH and EAST can't reference constant/field before they are defined:



              import java.util.function.Supplier;

              public enum Direction
              NORTH,
              EAST,
              SOUTH,
              WEST;

              private Supplier<Direction> opposite;

              private Direction()


              static // initialize opposite field
              for (final Direction direction : Direction.values())
              direction.opposite = oppositeOf(direction);



              private static Supplier<Direction> oppositeOf(final Direction self)
              switch (self)
              case NORTH: return () -> SOUTH;
              case WEST: return () -> EAST;
              case EAST: return () -> WEST;
              case SOUTH: return () -> NORTH;
              default: throw new IllegalStateException("Invalid opposite: " + self);



              public final Direction getOppositeDirection()
              return opposite.get();


              public static void main(final String args)
              for (final Direction dir : Direction.values())
              System.out.println(dir + " is opposite of " + dir.getOppositeDirection());





              This does the same than having abstract method, but is more concise (except here because you need to add more to the code): you read directly what is the opposite direction instead of having the verbose method declaration (it is another matter if you need to also add other methods).



              Also, it will not create pseudo class for each enums constant (eg: Direction$1, Direction$2, ...) because there is no need to.






              share|improve this answer














              You may also want to look in lambda for other case, but you will need to use a little cheat code because NORTH and EAST can't reference constant/field before they are defined:



              import java.util.function.Supplier;

              public enum Direction
              NORTH,
              EAST,
              SOUTH,
              WEST;

              private Supplier<Direction> opposite;

              private Direction()


              static // initialize opposite field
              for (final Direction direction : Direction.values())
              direction.opposite = oppositeOf(direction);



              private static Supplier<Direction> oppositeOf(final Direction self)
              switch (self)
              case NORTH: return () -> SOUTH;
              case WEST: return () -> EAST;
              case EAST: return () -> WEST;
              case SOUTH: return () -> NORTH;
              default: throw new IllegalStateException("Invalid opposite: " + self);



              public final Direction getOppositeDirection()
              return opposite.get();


              public static void main(final String args)
              for (final Direction dir : Direction.values())
              System.out.println(dir + " is opposite of " + dir.getOppositeDirection());





              This does the same than having abstract method, but is more concise (except here because you need to add more to the code): you read directly what is the opposite direction instead of having the verbose method declaration (it is another matter if you need to also add other methods).



              Also, it will not create pseudo class for each enums constant (eg: Direction$1, Direction$2, ...) because there is no need to.







              share|improve this answer














              share|improve this answer



              share|improve this answer








              edited yesterday

























              answered yesterday









              NoDataFound

              5,1511539




              5,1511539











              • I thought about it, but it shouldn't compile because there are 2 illegal forward references here.
                – Andrew Tobilko
                yesterday










              • There are no forward reference: it would make an error if I was passing the field directly in the constructor, but that is not the case here. The lambda is not evaluated before getOppositeDirection get called.
                – NoDataFound
                yesterday










              • it doesn't compile for me
                – Andrew Tobilko
                yesterday










              • You were right. There was an error for NORTH/EAST. Fixed it in answer.
                – NoDataFound
                yesterday










              • Suppliers are redundant when you use a static initialisation block
                – Andrew Tobilko
                yesterday
















              • I thought about it, but it shouldn't compile because there are 2 illegal forward references here.
                – Andrew Tobilko
                yesterday










              • There are no forward reference: it would make an error if I was passing the field directly in the constructor, but that is not the case here. The lambda is not evaluated before getOppositeDirection get called.
                – NoDataFound
                yesterday










              • it doesn't compile for me
                – Andrew Tobilko
                yesterday










              • You were right. There was an error for NORTH/EAST. Fixed it in answer.
                – NoDataFound
                yesterday










              • Suppliers are redundant when you use a static initialisation block
                – Andrew Tobilko
                yesterday















              I thought about it, but it shouldn't compile because there are 2 illegal forward references here.
              – Andrew Tobilko
              yesterday




              I thought about it, but it shouldn't compile because there are 2 illegal forward references here.
              – Andrew Tobilko
              yesterday












              There are no forward reference: it would make an error if I was passing the field directly in the constructor, but that is not the case here. The lambda is not evaluated before getOppositeDirection get called.
              – NoDataFound
              yesterday




              There are no forward reference: it would make an error if I was passing the field directly in the constructor, but that is not the case here. The lambda is not evaluated before getOppositeDirection get called.
              – NoDataFound
              yesterday












              it doesn't compile for me
              – Andrew Tobilko
              yesterday




              it doesn't compile for me
              – Andrew Tobilko
              yesterday












              You were right. There was an error for NORTH/EAST. Fixed it in answer.
              – NoDataFound
              yesterday




              You were right. There was an error for NORTH/EAST. Fixed it in answer.
              – NoDataFound
              yesterday












              Suppliers are redundant when you use a static initialisation block
              – Andrew Tobilko
              yesterday




              Suppliers are redundant when you use a static initialisation block
              – Andrew Tobilko
              yesterday










              up vote
              2
              down vote













              The concise answer is:



              public Direction getOppositeDirection() 
              return
              this==NORTH ? SOUTH :
              this==EAST ? WEST :
              this==SOUTH ? NORTH :
              EAST;



              You might prefer case statement



              public Direction getOppositeDirection() 
              switch (this)
              case NORTH: return SOUTH;
              case EAST: return WEST;
              case SOUTH: return NORTH;
              case WEST: return EAST;
              default: throw new Error();







              share|improve this answer
























                up vote
                2
                down vote













                The concise answer is:



                public Direction getOppositeDirection() 
                return
                this==NORTH ? SOUTH :
                this==EAST ? WEST :
                this==SOUTH ? NORTH :
                EAST;



                You might prefer case statement



                public Direction getOppositeDirection() 
                switch (this)
                case NORTH: return SOUTH;
                case EAST: return WEST;
                case SOUTH: return NORTH;
                case WEST: return EAST;
                default: throw new Error();







                share|improve this answer






















                  up vote
                  2
                  down vote










                  up vote
                  2
                  down vote









                  The concise answer is:



                  public Direction getOppositeDirection() 
                  return
                  this==NORTH ? SOUTH :
                  this==EAST ? WEST :
                  this==SOUTH ? NORTH :
                  EAST;



                  You might prefer case statement



                  public Direction getOppositeDirection() 
                  switch (this)
                  case NORTH: return SOUTH;
                  case EAST: return WEST;
                  case SOUTH: return NORTH;
                  case WEST: return EAST;
                  default: throw new Error();







                  share|improve this answer












                  The concise answer is:



                  public Direction getOppositeDirection() 
                  return
                  this==NORTH ? SOUTH :
                  this==EAST ? WEST :
                  this==SOUTH ? NORTH :
                  EAST;



                  You might prefer case statement



                  public Direction getOppositeDirection() 
                  switch (this)
                  case NORTH: return SOUTH;
                  case EAST: return WEST;
                  case SOUTH: return NORTH;
                  case WEST: return EAST;
                  default: throw new Error();








                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered yesterday









                  Tom Hawtin - tackline

                  124k27179265




                  124k27179265




















                      up vote
                      1
                      down vote













                      Another option could be to use a Map (perhaps even an EnumMap), e.g.:



                      public enum Direction 

                      NORTH,
                      EAST,
                      SOUTH,
                      WEST;

                      private static final Map<Direction, Direction> OPPOSITES = ImmutableMap.of(
                      NORTH, SOUTH,
                      EAST, WEST,
                      SOUTH, NORTH,
                      WEST, EAST
                      );

                      public Direction oppositeDirection()
                      return OPPOSITES.get(this);







                      share|improve this answer




















                      • I don't understand the downvote - this is the very first thing I thought about when reading the question, 1+
                        – Eugene
                        yesterday










                      • There was this one too :) but you should provide a solution using EnumMap and not Guava.
                        – NoDataFound
                        yesterday















                      up vote
                      1
                      down vote













                      Another option could be to use a Map (perhaps even an EnumMap), e.g.:



                      public enum Direction 

                      NORTH,
                      EAST,
                      SOUTH,
                      WEST;

                      private static final Map<Direction, Direction> OPPOSITES = ImmutableMap.of(
                      NORTH, SOUTH,
                      EAST, WEST,
                      SOUTH, NORTH,
                      WEST, EAST
                      );

                      public Direction oppositeDirection()
                      return OPPOSITES.get(this);







                      share|improve this answer




















                      • I don't understand the downvote - this is the very first thing I thought about when reading the question, 1+
                        – Eugene
                        yesterday










                      • There was this one too :) but you should provide a solution using EnumMap and not Guava.
                        – NoDataFound
                        yesterday













                      up vote
                      1
                      down vote










                      up vote
                      1
                      down vote









                      Another option could be to use a Map (perhaps even an EnumMap), e.g.:



                      public enum Direction 

                      NORTH,
                      EAST,
                      SOUTH,
                      WEST;

                      private static final Map<Direction, Direction> OPPOSITES = ImmutableMap.of(
                      NORTH, SOUTH,
                      EAST, WEST,
                      SOUTH, NORTH,
                      WEST, EAST
                      );

                      public Direction oppositeDirection()
                      return OPPOSITES.get(this);







                      share|improve this answer












                      Another option could be to use a Map (perhaps even an EnumMap), e.g.:



                      public enum Direction 

                      NORTH,
                      EAST,
                      SOUTH,
                      WEST;

                      private static final Map<Direction, Direction> OPPOSITES = ImmutableMap.of(
                      NORTH, SOUTH,
                      EAST, WEST,
                      SOUTH, NORTH,
                      WEST, EAST
                      );

                      public Direction oppositeDirection()
                      return OPPOSITES.get(this);








                      share|improve this answer












                      share|improve this answer



                      share|improve this answer










                      answered yesterday









                      Koekje

                      292315




                      292315











                      • I don't understand the downvote - this is the very first thing I thought about when reading the question, 1+
                        – Eugene
                        yesterday










                      • There was this one too :) but you should provide a solution using EnumMap and not Guava.
                        – NoDataFound
                        yesterday

















                      • I don't understand the downvote - this is the very first thing I thought about when reading the question, 1+
                        – Eugene
                        yesterday










                      • There was this one too :) but you should provide a solution using EnumMap and not Guava.
                        – NoDataFound
                        yesterday
















                      I don't understand the downvote - this is the very first thing I thought about when reading the question, 1+
                      – Eugene
                      yesterday




                      I don't understand the downvote - this is the very first thing I thought about when reading the question, 1+
                      – Eugene
                      yesterday












                      There was this one too :) but you should provide a solution using EnumMap and not Guava.
                      – NoDataFound
                      yesterday





                      There was this one too :) but you should provide a solution using EnumMap and not Guava.
                      – NoDataFound
                      yesterday











                      up vote
                      0
                      down vote













                      I feel like the easiest way would be to do it the way you originally proposed, but accept a parameter in the constructor:



                      public static enum Direction 
                      NORTH(0),
                      WEST(1),
                      SOUTH(2),
                      EAST(3);

                      private int dir;

                      private Direction(int dir)
                      this.dir = dir;


                      public static Direction getNewDirection(int dir)
                      // ensure direction is in [0, 4)
                      dir %= 4;
                      if (dir < 0) dir += 4;
                      for (Direction d : Direction.values())
                      if (d.dir == dir) return d;

                      throw new Error();


                      public Direction getOppositeDirection()
                      return getNewDirection(dir + 2);




                      The advantages to this are numerous: directions essentially form a group of rotations, which correspond to the integers modulo 4. They have a natural representation as integers modulo 4. Now, if we want to get the direction that is clockwise, we can do that easily (getNewDirection(dir + 1)), or counterclockwise (getNewDirection(dir - 1)). If the character is facing direction d1 and we want to know which way to turn to face a new direction d2, this corresponds to subtraction, etc. All of the operations that you might want to do have a natural way to do it with the integers modulo 4.






                      share|improve this answer
























                        up vote
                        0
                        down vote













                        I feel like the easiest way would be to do it the way you originally proposed, but accept a parameter in the constructor:



                        public static enum Direction 
                        NORTH(0),
                        WEST(1),
                        SOUTH(2),
                        EAST(3);

                        private int dir;

                        private Direction(int dir)
                        this.dir = dir;


                        public static Direction getNewDirection(int dir)
                        // ensure direction is in [0, 4)
                        dir %= 4;
                        if (dir < 0) dir += 4;
                        for (Direction d : Direction.values())
                        if (d.dir == dir) return d;

                        throw new Error();


                        public Direction getOppositeDirection()
                        return getNewDirection(dir + 2);




                        The advantages to this are numerous: directions essentially form a group of rotations, which correspond to the integers modulo 4. They have a natural representation as integers modulo 4. Now, if we want to get the direction that is clockwise, we can do that easily (getNewDirection(dir + 1)), or counterclockwise (getNewDirection(dir - 1)). If the character is facing direction d1 and we want to know which way to turn to face a new direction d2, this corresponds to subtraction, etc. All of the operations that you might want to do have a natural way to do it with the integers modulo 4.






                        share|improve this answer






















                          up vote
                          0
                          down vote










                          up vote
                          0
                          down vote









                          I feel like the easiest way would be to do it the way you originally proposed, but accept a parameter in the constructor:



                          public static enum Direction 
                          NORTH(0),
                          WEST(1),
                          SOUTH(2),
                          EAST(3);

                          private int dir;

                          private Direction(int dir)
                          this.dir = dir;


                          public static Direction getNewDirection(int dir)
                          // ensure direction is in [0, 4)
                          dir %= 4;
                          if (dir < 0) dir += 4;
                          for (Direction d : Direction.values())
                          if (d.dir == dir) return d;

                          throw new Error();


                          public Direction getOppositeDirection()
                          return getNewDirection(dir + 2);




                          The advantages to this are numerous: directions essentially form a group of rotations, which correspond to the integers modulo 4. They have a natural representation as integers modulo 4. Now, if we want to get the direction that is clockwise, we can do that easily (getNewDirection(dir + 1)), or counterclockwise (getNewDirection(dir - 1)). If the character is facing direction d1 and we want to know which way to turn to face a new direction d2, this corresponds to subtraction, etc. All of the operations that you might want to do have a natural way to do it with the integers modulo 4.






                          share|improve this answer












                          I feel like the easiest way would be to do it the way you originally proposed, but accept a parameter in the constructor:



                          public static enum Direction 
                          NORTH(0),
                          WEST(1),
                          SOUTH(2),
                          EAST(3);

                          private int dir;

                          private Direction(int dir)
                          this.dir = dir;


                          public static Direction getNewDirection(int dir)
                          // ensure direction is in [0, 4)
                          dir %= 4;
                          if (dir < 0) dir += 4;
                          for (Direction d : Direction.values())
                          if (d.dir == dir) return d;

                          throw new Error();


                          public Direction getOppositeDirection()
                          return getNewDirection(dir + 2);




                          The advantages to this are numerous: directions essentially form a group of rotations, which correspond to the integers modulo 4. They have a natural representation as integers modulo 4. Now, if we want to get the direction that is clockwise, we can do that easily (getNewDirection(dir + 1)), or counterclockwise (getNewDirection(dir - 1)). If the character is facing direction d1 and we want to know which way to turn to face a new direction d2, this corresponds to subtraction, etc. All of the operations that you might want to do have a natural way to do it with the integers modulo 4.







                          share|improve this answer












                          share|improve this answer



                          share|improve this answer










                          answered yesterday









                          soktinpk

                          2,91321027




                          2,91321027












                              Popular posts from this blog

                              How to check contact read email or not when send email to Individual?

                              Bahrain

                              Postfix configuration issue with fips on centos 7; mailgun relay