实现响应方向枚举的最简单方法是什么?JAVA
我将以“最清晰”的方式快速展示我想要实现的目标: 因此,我希望这两个枚举能够安全高效地根据移动查找更改的方向:实现响应方向枚举的最简单方法是什么?JAVA,java,enums,direction,Java,Enums,Direction,我将以“最清晰”的方式快速展示我想要实现的目标: 因此,我希望这两个枚举能够安全高效地根据移动查找更改的方向: Orientation orient = Orientation.NORTH; // orient points to NORTH now orient = orient.turn(Turn.LEFT); // orient points to WEST now 我尝试实现这一目标的第一种方法是创建地图: EnumMap<Orientation, EnumMap<Tur
Orientation orient = Orientation.NORTH;
// orient points to NORTH now
orient = orient.turn(Turn.LEFT);
// orient points to WEST now
我尝试实现这一目标的第一种方法是创建地图:
EnumMap<Orientation, EnumMap<Turn, Orientation>>
接下来我学习了一门罗盘课程,它将所有方向连接成一个圆圈。。像链接电路列表一样工作…东北西南北。。。所以Compass可以有一个静态函数,调用链表中的任何成员并向左或向右移动,从而正确改变方向。但是代码并没有按照我想要的方式运行
因此,最后我的问题是,有没有人对这类代码有经验,或者有没有人知道如何以一种很好的枚举方式实现所需的结果?我认为Map解决方案没有任何问题。如果您想要更贴心的东西:
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];
}
}
然而,这是不太干净和可维护的(如果有人更改枚举的顺序,它将中断)
稍微干净一点(但不那么体贴):
我认为你关于循环列表的想法非常好:
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);
}
}
公共枚举回合{
左(-1),右(1);
私人最终整数偏移;
专用转弯(内偏移){
这个偏移量=偏移量;
}
公共整数偏移量(){
返回此.offset;
}
}
面向公共枚举{
北、东、南、西;
私有静态最终列表方向=
Arrays.asList(北、东、南、西);//不依赖于序号
公众导向转向(转向){
int size=orientations.size();
int myIndex=方向.indexOf(this);
整数余数=(myIndex+to.offset())%size;
整数索引=余数<0?大小+余数:余数;
返回方向。获取(索引);
}
}
这似乎是非常可扩展的,即HARD_LEFT将有一个
-2
偏移量,方向的循环列表应该从左到右排序。不使用序数,并且易于理解:
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; }
}
欺骗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();
}
}
您可以保存
turn()
,如果愿意,只需编写类似于Orientation.North.left()
的内容。为您提供非常简洁的语法。我不确定是否理解。你是在问我们如何在方向枚举中实现turn()方法吗?我是在问如何以一种好的、非冗余的方式实现这种方法的想法(你总是可以编写一个switch case,但这在冗余方面是不好的,例如WEST。turn(LEFT)总是会导致同一个方向,即SOUTH)@Jan您真的需要回合
的枚举吗?我的意思是,只能是左
或右
/@RohitJain。我想,在这种情况下,总是建议使用枚举。在我正在编写的实际代码中,转弯是硬左、左、右、硬右,方向是N、NE、E、SE、S、SW、W、NW,我认为关联数组在这里有点合适。在这种情况下,您必须了解如何正确地实现它。我认为Map
是你需要的东西。是的,不幸的是,我读到Josh Bloch告诉我不要使用顺序索引,原因与你告诉我的完全相同。关于你认为MAP解决方案是好的,正如你在上面的评论中看到的,我有更多的方向和可能的可能性,导致静态映射(40行)的代码块更大。这仍然被认为是一个好的解决方案吗?@Jan:我想说,如果逻辑更复杂,地图解决方案会更好。也许你可以通过在方向和转弯处(比如表示度)都添加一个数字代码来简化它的构造逻辑(避免过多的if/else)。我真的没有考虑使用模类来获得正确的索引和管理溢出。。非常感谢。这实际上是一种很好的方法:)这会导致数组索引越界异常!java中的数组不像C中的数组那样将-1索引作为数组的结尾。这个答案应该得到更正。@Jan该异常何时发生?异常为:ArrayIndexOutOfBoundsException:-1,异常的示例代码:Orientation=Orientation.NORTH;转向(左转)@简:我刚才注意到了。我将为每个Java版本添加一个版本。
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);
}
}
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; }
}
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();
}
}