使用Guava Iterables.cycle作为循环列表impl

sme*_*eeb 2 java algorithm list guava data-structures

我有一个List<Widget>并且正在寻找最有效/优雅的解决方案来循环它,一次又一次(有点像循环算法):

// Returns a list of 20 widgets, with an id of 1 - 20 respectively.
List<Widget> widgets = getWidgets();
Widget widget = pickWidget(); // Returns the 1st widget with id = 1.
widget = pickWidget(); // Returns the 2nd widget with id = 2.
widget = pickWidget(); // Return the 3rd widget with id = 3.
// ..etc.
widget = pickWidget(); // Returns the 19th widget with id = 19.
widget = pickWidget(); // Returns the 20th widget with id = 20.
widget = pickWidget(); // Returns the 1st widget with id = 1 (it cycle back).
Run Code Online (Sandbox Code Playgroud)

这是用法,对于实现我能找到的最好的是Guava Iterables.cycle(...):

Widget pickWidget() {
    for(Widget w : Iterables.cycle(widgets)) {
        return w;
    }
}
Run Code Online (Sandbox Code Playgroud)

问题是cycle不会在内部留下一个标记,widgets以便它可以"记住"最后一次pickWidget()调用的位置.

这里有什么想法?Apache CircularFifoQueue似乎很接近但没有雪茄,因为我不希望任何东西从队列中弹出,我只是希望它在调用时一次又一次地在同一个列表中循环.

JB *_*zet 11

它不需要留下任何标记.cycle()返回的Iterable的迭代器在内部保留该标记.您只需要保留对此迭代器的引用:

private Iterator<Widget> cyclingIterator = Iterables.cycle(widgets).iterator();

public Widget pick() {
    return cyclingIterator.next();
}
Run Code Online (Sandbox Code Playgroud)

或者简单地说,因为你实际上并不需要Iterable,而只需要迭代器:

private Iterator<Widget> cyclingIterator = Iterators.cycle(widgets);

public Widget pick() {
    return cyclingIterator.next();
}
Run Code Online (Sandbox Code Playgroud)