簡體   English   中英

實現響應式定向枚舉的最簡單方法是什么? java的

[英]The easiest way to achieve a responsive orientation enum? java

我將以“最清晰”的方式快速展示我想要實現的目標:

public enum Orientation {
    NORTH, WEST, SOUTH, EAST }

public enum Turn {
    LEFT, RIGHT }

因此,我希望這兩個枚舉能夠安全有效地根據移動查找更改的方向:

Orientation orient = Orientation.NORTH;
// orient points to NORTH now
orient = orient.turn(Turn.LEFT);
// orient points to WEST now

我嘗試實現這一目標的第一種方法是創建一個地圖:

 EnumMap<Orientation, EnumMap<Turn, Orientation>>

並靜態映射所有方向,但這是一大塊map.get.put.get ....並且可能有點過量,導致這種期望的效果:

directionMap.get(NORTH).get(LEFT)
// the value would then be WEST

我接下來的方式是通過Compass類將所有方向鏈接成一個圓圈。像LinkedCircuitList一樣...... < - > NORTH < - > EAST < - > SOUTH < - > WEST < - > NORTH < - >。 ..因此Compass可以有一個靜態函數,可以調用該鏈表的任何成員並向左或向右移動,從而導致方向的正確更改。 但是代碼並沒有按照我想要的方式運行。

所以我的問題到底是什么,有沒有人有這種代碼的經驗,或者知道如何以一種美好的方式實現理想的結果?

我認為地圖解決方案沒有錯。 如果你想要更簡潔的東西:

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

欺騙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()這樣的東西。 為您提供非常簡潔的語法。

我認為你對循環列表的想法非常好:

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

這似乎是非常可擴展的,即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; }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM