[英]The easiest way to achieve a responsive orientation enum? java
I will quickly display what I want to achieve in the "clearest" way: 我将以“最清晰”的方式快速展示我想要实现的目标:
public enum Orientation {
NORTH, WEST, SOUTH, EAST }
public enum Turn {
LEFT, RIGHT }
So what I want those two enums to do is secure and efficiently look up the changed orientation according to the move: 因此,我希望这两个枚举能够安全有效地根据移动查找更改的方向:
Orientation orient = Orientation.NORTH;
// orient points to NORTH now
orient = orient.turn(Turn.LEFT);
// orient points to WEST now
The first way I tried to achieve this was through creating a map: 我尝试实现这一目标的第一种方法是创建一个地图:
EnumMap<Orientation, EnumMap<Turn, Orientation>>
And map all the directions statically but that is a huge chunk of map.get.put.get.... and is probably a bit too overdosed, altough resulting in this desired effect: 并静态映射所有方向,但这是一大块map.get.put.get ....并且可能有点过量,导致这种期望的效果:
directionMap.get(NORTH).get(LEFT)
// the value would then be WEST
The next way I went was through a Compass class that links all orientations into a circle.. Working like a LinkedCircuitList ...<->NORTH<->EAST<->SOUTH<->WEST<->NORTH<->... So Compass could have a static function that calls any Member of that linked list and step to the left or to the right, resulting in the correct change of direction. 我接下来的方式是通过Compass类将所有方向链接成一个圆圈。像LinkedCircuitList一样...... < - > NORTH < - > EAST < - > SOUTH < - > WEST < - > NORTH < - >。 ..因此Compass可以有一个静态函数,可以调用该链表的任何成员并向左或向右移动,从而导致方向的正确更改。 But the code did not really work out the way I wanted it.
但是代码并没有按照我想要的方式运行。
So my question in the end, does anybody has experience on that kind of code, or has an idea how to achieve the desired result in a nice enumerish way? 所以我的问题到底是什么,有没有人有这种代码的经验,或者知道如何以一种美好的方式实现理想的结果?
I see nothing wrong with the Map solution. 我认为地图解决方案没有错。 If you want something more consise:
如果你想要更简洁的东西:
public enum Orientation {
NORTH, EAST, SOUTH, WEST;
private static Orientation[] vals = values();
Orientation turnTo(Turn t) {
return vals[(4 + this.ordinal() + (t == Turn.RIGHT ? 1 : -1)) % 4];
}
}
This, however, is less clean and maintainable (it would break if someone changes the order of the enums). 然而,这不太干净和可维护(如果有人改变了枚举的顺序,它会破裂)。
A little cleaner (but less consise) : 一点点清洁(但不太明确):
public enum Orientation {
NORTH(0), EAST(1), SOUTH(2), WEST(3);
private final int p;
Orientation(int p) {
this.p = p;
}
private static Orientation[] vals = new Orientation[4];
static {
for( Orientation o : Orientation.values() )
vals[o.p] = o;
}
Orientation turnTo(Turn t) {
return vals[(4 + this.p + (t == Turn.RIGHT ? 1 : -1)) % 4];
}
}
Another way to trick java into accepting this is using methods instead of fields: 欺骗java接受这个的另一种方法是使用方法而不是字段:
enum Orientation {
NORTH {
Orientation left(){return WEST;}
Orientation right(){return EAST;}
},
EAST {
Orientation left(){return NORTH;}
Orientation right(){return SOUTH;}
},
SOUTH {
Orientation left(){return EAST;}
Orientation right(){return WEST;}
},
WEST {
Orientation left(){return SOUTH;}
Orientation right(){return NORTH;}
};
abstract Orientation left();
abstract Orientation right();
public Orientation turn(Turn where){
return where == Turn.LEFT ? this.left() : this.right();
}
}
You can save yourself the turn()
and just write stuff like Orientation.North.left()
, if you want to. 如果你愿意,你可以保存自己的
turn()
并只写像Orientation.North.left()
这样的东西。 Gives you very concise Syntax. 为您提供非常简洁的语法。
I think your idea of a circular list is very good: 我认为你对循环列表的想法非常好:
public enum Turn {
LEFT(-1), RIGHT(1);
private final int offset;
private Turn(int offset) {
this.offset = offset;
}
public int offset() {
return this.offset;
}
}
public enum Orientation {
NORTH, EAST, SOUTH, WEST;
private static final List<Orientation> orientations =
Arrays.asList(NORTH, EAST, SOUTH, WEST); // to not depend on ordinal
public Orientation turn(Turn to) {
int size = orientations.size();
int myIndex = orientations.indexOf(this);
int remainder = (myIndex + to.offset()) % size;
int index = remainder < 0 ? size + remainder : remainder;
return orientations.get(index);
}
}
This seems quite extensible, ie HARD_LEFT would have a -2
offset and the circular list of orientations should be ordered from left to right. 这似乎是非常可扩展的,即HARD_LEFT将具有
-2
偏移,并且循环的方向列表应该从左到右排序。
Does not use ordinals, and easy to understand: 不使用序数,易于理解:
public enum Orientation { NORTH, WEST, EAST, SOUTH;
static {
NORTH.left = WEST;
NORTH.right = EAST;
WEST.left = SOUTH;
WEST.right = NORTH;
EAST.left = NORTH;
EAST.right = SOUTH;
SOUTH.left = EAST;
SOUTH.right = WEST;
}
private Orientation left;
private Orientation right;
public Orientation turnTo(Turn t) { return t == Turn.LEFT ? left : right; }
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.