5

列挙型に対する循環トラバーサルの最良の方法は何ですか。

私は enum Directions を持っていて、それを循環的にたどりたいと思っています。現在、次の値を返す enum に次のメソッドを実装しています。巡回トラバーサルのより良い方法/組み込みのサポートがあるのではないかと思っていました。

現在のコード

enum Direction {
    east, north, west, south;

    Direction next() {

        switch (this) {
        case east:
            return north;

        case north:
            return west;

        case west:
            return south;

        case south:
            return east;
        }

        return null;
    }
}
4

3 に答える 3

8

サイクリックを実装するのは非常に簡単Iteratorです:

enum Direction implements Iterable<Direction> {
    east, north, west, south;

    @Override
    public Iterator<Direction> iterator() {
        return new DirectionIterator();
    }

    class DirectionIterator implements Iterator<Direction> {

        Direction next = Direction.this;

        @Override
        public Direction next() {
            try {
                return next;
            } finally {
                next = values()[(next.ordinal() + 1) % values().length];
            }
        }

        @Override
        public boolean hasNext() { 
            return true; 
        }

        @Override
        public void remove() {
            throw new NotImplementedException();
        }
    }
}

使用法:

public static void main(String[] args) {

    Iterator<Direction> it = Direction.north.iterator();

    for (int i = 0; i < 10; i++)
        System.out.println(it.next());
}

出力:

north
west
south
east
north
west
south
east
north
west
于 2012-05-28T11:13:11.133 に答える
7

( を介して) int に変換しordinal()、循環して列挙型に戻します ( を介してvalues[i])。

このような:

Direction next() {
    return values()[(ordinal() + 1) % values().length];
}

一般的なソリューション

列挙値を循環するより一般的な方法は次のとおりです。

class CyclicIterator<T> implements Iterator<T> {

    private final T[] values;
    private int current;

    public CyclicIterator(T[] values) {
        this.values = values;
        this.current = 0;
    }

    @Override
    public boolean hasNext() {
        return true;
    }

    @Override
    public T next() {
        current = (current + 1) % values.length;
        return values[current];
    }
}

次のように使用できます。

CyclicIterator<Direction> iter = new CyclicIterator<>(Direction.values());
for (int i = 0; i < 6; i++) {
    System.out.println(i + ": " + iter.next());
}

出力:

0: north
1: west
2: south
3: east
4: north
5: west

グアバ溶液

Guava に依存している場合、循環イテレーター (上記のものと同じ) はすでにIterators.cycle

于 2012-05-28T11:06:23.190 に答える
1

列挙値が整数値に割り当てられているという事実を使用して、それらを循環させることができます。

于 2012-05-28T11:06:15.703 に答える