自定义类项列表的循环迭代器/生成器

7

假设我有一个自定义类:

public class CustomClass {
    private String name;
    private String data;

    public CustomClass(String name, String data) {
        this.name = name;
        this.data = data;
    }
}

我还有一个我的自定义类对象的列表:

CustomClass[] list = new CustomClass[] {
    new CustomClass("Item 1", "data"),
    new CustomClass("Item 2", "data"),
    new CustomClass("Item 3", "data"),
    new CustomClass("Item 4", "data"),
    new CustomClass("Item 5", "data"),
};

如何创建一个迭代器(或生成器),使其在列表中循环K次(K > list.length),每次给我下一个元素?
我希望使用“内联”解决方案(不创建任何新类)。
例如,我需要依次获取我的CustomClass列表项7次。该解决方案应按照以下顺序检索CustomClass对象:
- 项目1 - 项目2 - 项目3 - 项目4 - 项目5 - 项目1 - 项目2

1
Iterator是一个接口。要创建一种新类型的迭代器,你必须创建一个新的类,即使只是匿名的。 - Andreas
@Andreas 确实 - 我想我是指避免在主函数之外的某个地方定义,因为我希望保持代码的可读性。 - Morphing Coffee
5个回答

6

使用索引取模数组长度:

for( int i = 0; i < K; i++ ) {
   list[ i % list.length ];
}

当第一个索引(这里命名为i)大于或等于列表长度时,它将"重置"它,因为取模运算符(%)返回整数除法后的余数。

该解决方案不引入任何类。


5

试试这个。

static <T> Iterator<T> circularIterator(List<T> list, int count) {
    int size = list.size();
    return new Iterator<T>() {

        int i = 0;

        @Override
        public boolean hasNext() {
            return i < count;
        }

        @Override
        public T next() {
            return list.get(i++ % size);
        }
    };
}

而且
List<String> list = Arrays.asList("a", "b", "c");
for (Iterator<String> i = circularIterator(list, 5); i.hasNext();) {
    String s = i.next();
    System.out.println(s);
}

结果:

a
b
c
a
b

4
这个的简单方法是:
import com.google.common.collect.Iterables
import com.google.common.collect.Iterators;

Integer[] arr = {1,2,3,4,5};
Iterator<Integer> iter = Iterators.limit(Iterables.cycle(arr).iterator(),7) ;

1
请使用Iterators.limit()来实现这个功能! - German

1
为了拥有一个循环迭代器,您可以使用Apache的commons-collections4中的LoopingIteratorLoopingListIterator
该迭代器将在提供的元素周围不断循环,除非一开始就没有元素或所有元素都被删除。
import java.util.Arrays;
import java.util.Iterator;
import org.apache.commons.collections4.iterators.LoopingIterator;

void circularIterator() {
  CustomClass[] list = new CustomClass[]{
      new CustomClass("Item 1", "data"),
      new CustomClass("Item 2", "data"),
      new CustomClass("Item 3", "data"),
      new CustomClass("Item 4", "data"),
      new CustomClass("Item 5", "data"),
  };

  final Iterator<CustomClass> circularIterator =
      new LoopingIterator(Arrays.asList(list));
  while (circularIterator.hasNext()) {
    CustomClass next = circularIterator.next();
    System.out.println(next.getName());
  }
}

代码生成以下内容:
Item 1
Item 2
Item 3
Item 4
Item 5
Item 1
Item 2
Item 3
Item 4
Item 5
Item 1
Item 2
Item 3
Item 4
Item 5
Item 1
...
// This would never end

1
这是一种适用于Java 8的方法:
IntStream.range(0, K)
    .mapToObj(i -> list[i % list.length])
    .forEach(cc -> /* play with CustomClass cc instance */);

1
.map -> .mapToObj. - user4910279

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接