Enum of directions with opposites [duplicate]
Clash Royale CLAN TAG#URR8PPP
up vote
10
down vote
favorite
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?
java enums
marked as duplicate by Boann
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.
add a comment |Â
up vote
10
down vote
favorite
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?
java enums
marked as duplicate by Boann
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.
add a comment |Â
up vote
10
down vote
favorite
up vote
10
down vote
favorite
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?
java enums
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
java enums
edited yesterday
Communityâ¦
11
11
asked yesterday
Rémy.W
887
887
marked as duplicate by Boann
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
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.
add a comment |Â
add a comment |Â
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;
1
What even isNORTH()
? Is it a method? A field?
â David Stockinger
yesterday
NORTH
is a constant instance ofDirection
; in order to be a valid one, it should provide an implementation for all the abstract methods declared
â Andrew Tobilko
yesterday
@DavidStockingerNORTH() ...
is the way to determine a constructor to call and to provide/override methods. Here, it's the default constructor. If we had aDirection(String s)
constructor, we could useNORTH("string") ...
.
â Andrew Tobilko
yesterday
1
@AndrewTobilko this also adds an extra bonus, that if you wanted to add extra direction, likeSOUTH-EAST
- it would not compile without providing an opposite.
â Eugene
yesterday
add a comment |Â
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.
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
Supplier
s are redundant when you use a static initialisation block
â Andrew Tobilko
yesterday
 |Â
show 1 more comment
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();
add a comment |Â
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);
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
add a comment |Â
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.
add a comment |Â
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;
1
What even isNORTH()
? Is it a method? A field?
â David Stockinger
yesterday
NORTH
is a constant instance ofDirection
; in order to be a valid one, it should provide an implementation for all the abstract methods declared
â Andrew Tobilko
yesterday
@DavidStockingerNORTH() ...
is the way to determine a constructor to call and to provide/override methods. Here, it's the default constructor. If we had aDirection(String s)
constructor, we could useNORTH("string") ...
.
â Andrew Tobilko
yesterday
1
@AndrewTobilko this also adds an extra bonus, that if you wanted to add extra direction, likeSOUTH-EAST
- it would not compile without providing an opposite.
â Eugene
yesterday
add a comment |Â
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;
1
What even isNORTH()
? Is it a method? A field?
â David Stockinger
yesterday
NORTH
is a constant instance ofDirection
; in order to be a valid one, it should provide an implementation for all the abstract methods declared
â Andrew Tobilko
yesterday
@DavidStockingerNORTH() ...
is the way to determine a constructor to call and to provide/override methods. Here, it's the default constructor. If we had aDirection(String s)
constructor, we could useNORTH("string") ...
.
â Andrew Tobilko
yesterday
1
@AndrewTobilko this also adds an extra bonus, that if you wanted to add extra direction, likeSOUTH-EAST
- it would not compile without providing an opposite.
â Eugene
yesterday
add a comment |Â
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;
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;
edited yesterday
answered yesterday
Andrew Tobilko
22.4k83877
22.4k83877
1
What even isNORTH()
? Is it a method? A field?
â David Stockinger
yesterday
NORTH
is a constant instance ofDirection
; in order to be a valid one, it should provide an implementation for all the abstract methods declared
â Andrew Tobilko
yesterday
@DavidStockingerNORTH() ...
is the way to determine a constructor to call and to provide/override methods. Here, it's the default constructor. If we had aDirection(String s)
constructor, we could useNORTH("string") ...
.
â Andrew Tobilko
yesterday
1
@AndrewTobilko this also adds an extra bonus, that if you wanted to add extra direction, likeSOUTH-EAST
- it would not compile without providing an opposite.
â Eugene
yesterday
add a comment |Â
1
What even isNORTH()
? Is it a method? A field?
â David Stockinger
yesterday
NORTH
is a constant instance ofDirection
; in order to be a valid one, it should provide an implementation for all the abstract methods declared
â Andrew Tobilko
yesterday
@DavidStockingerNORTH() ...
is the way to determine a constructor to call and to provide/override methods. Here, it's the default constructor. If we had aDirection(String s)
constructor, we could useNORTH("string") ...
.
â Andrew Tobilko
yesterday
1
@AndrewTobilko this also adds an extra bonus, that if you wanted to add extra direction, likeSOUTH-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
add a comment |Â
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.
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
Supplier
s are redundant when you use a static initialisation block
â Andrew Tobilko
yesterday
 |Â
show 1 more comment
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.
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
Supplier
s are redundant when you use a static initialisation block
â Andrew Tobilko
yesterday
 |Â
show 1 more comment
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.
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.
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
Supplier
s are redundant when you use a static initialisation block
â Andrew Tobilko
yesterday
 |Â
show 1 more comment
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
Supplier
s 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
Supplier
s are redundant when you use a static initialisation blockâ Andrew Tobilko
yesterday
Supplier
s are redundant when you use a static initialisation blockâ Andrew Tobilko
yesterday
 |Â
show 1 more comment
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();
add a comment |Â
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();
add a comment |Â
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();
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();
answered yesterday
Tom Hawtin - tackline
124k27179265
124k27179265
add a comment |Â
add a comment |Â
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);
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
add a comment |Â
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);
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
add a comment |Â
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);
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);
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
add a comment |Â
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
add a comment |Â
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.
add a comment |Â
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.
add a comment |Â
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.
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.
answered yesterday
soktinpk
2,91321027
2,91321027
add a comment |Â
add a comment |Â