5

对枚举进行循环遍历的最佳方法是什么。

我有一个枚举方向,我想循环遍历它。目前我已经在枚举中实现了返回下一个值的下一个方法,我只是想知道是否有更好的方法/内置支持循环遍历。

当前代码

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 回答