Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/380.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
实现响应方向枚举的最简单方法是什么?JAVA_Java_Enums_Direction - Fatal编程技术网

实现响应方向枚举的最简单方法是什么?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();
    }
}