Java Enum Methods - Return Opposite Direction Enum

Java Enum Methods - return opposite direction enum

For those lured here by title: yes, you can define your own methods in your enum.

If you are wondering how to invoke your own non-static enum methods, you do it same way as with any other non-static method - you invoke it on instance of type which defines/inherits such method.

In case of enums such instances are simply ENUM_VALUEs themselves.

So all you need is YourEnum.YOUR_ENUM_VALUE.yourMethod(arguments).


Now lets go back to the problem from question. One of solutions could be

public enum Direction {

NORTH, SOUTH, EAST, WEST;

private Direction opposite;

static {
NORTH.opposite = SOUTH;
SOUTH.opposite = NORTH;
EAST.opposite = WEST;
WEST.opposite = EAST;
}

public Direction getOppositeDirection() {
return opposite;
}

}

Now Direction.NORTH.getOppositeDirection() will return Direction.SOUTH.


Here is little more "hacky" way to illustrate @jedwards comment but it doesn't feel as flexible as first approach since adding more fields or changing their order will break our code.

public enum Direction {
NORTH, EAST, SOUTH, WEST;

// cached values to avoid recreating such array each time method is called
private static final Direction[] VALUES = values();

public Direction getOppositeDirection() {
return VALUES[(ordinal() + 2) % 4];
}
}

Enum of directions with opposites

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

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

Simplest, I think, is just to add a method to it. Note that this only works well if the number of enum constants won't change over time.

enum Dir {
NORTH,
SOUTH,
EAST,
WEST;

public Dir opposite() {
switch(this) {
case NORTH: return Dir.SOUTH;
case SOUTH: return Dir.NORTH;
case EAST: return Dir.WEST;
case WEST: return Dir.EAST;
default: throw new IllegalStateException("This should never happen: " + this + " has no opposite.");
}
}
}

Then, in your code, you could do this:

randomNeighbor.walls.put(randDir.opposite(), false);

Java Enum linking to another Enum

One of the possible solution - you can encapsulate this login within the method

public Direction getOpposite() {
switch (this) {
case Up:
return Down;
case Down:
return Up;
case Left:
return Right;
case Right:
return Left;
}
return null;
}

It will be the same interface for classes that will use this enum

Java: Is there a way to get methods with different return types in a enum?

Yes, java allows to "reduce" the return type (see here).

But in your context, this does not make sense conceptually!

Think of

TestEnum someEnum = ...
Integer val = someEnum.getValue();

How is the compiler supposed to know which one of your enum constants you actually assigned to that value?

Therefore the compiler could only understand:

 Integer val = TestEnum.TEST_INTEGER.getValue();

But well, what if you just know that it is some instance of TestEnum you are dealing with?!

How to change an enum value in Java?

You can add the turnLeft/ turnRight methods directly inside the enum.

enum Direction{
UP, RIGHT, DOWN, LEFT;

public Direction turnLeft() {
switch(this) {
case UP: return LEFT;
case RIGHT: return UP;
case DOWN: return RIGHT;
default: return DOWN; // if you leave the LEFT case, you still need to return something outside the block on some Java versions
}
}
}

and then whenever you want to make a turn, you can assign the "left" value to the direction variable.

private Direction direction = Direction.DOWN;

public void turnAndPrint() {
direction = direction.turnLeft();
System.out.println(direction.name()); // will print RIGHT when called the first time
}

How to write the code if the direction is opposite of the other?

return getOpposite() == other;


Related Topics



Leave a reply



Submit