有没有Python的“枚举”函数的Java等效物?

2022-08-31 11:54:28

在Python中,枚举函数允许您循环访问一系列(索引,值)对。例如:

>>> numbers = ["zero", "one", "two"]
>>> for i, s in enumerate(numbers):
...     print i, s
... 
0 zero
1 one
2 two

在Java中有什么方法可以做到这一点吗?


答案 1

对于实现 List 接口的集合,可以调用 listIterator() 方法来获取 ListIterator。迭代器有两种方法 - nextIndex(),用于获取索引;和 next(),以获取值(如其他迭代器)。

因此,上面Python的Java等效物可能是:

import java.util.ListIterator;  
import java.util.List;

List<String> numbers = Arrays.asList("zero", "one", "two");
ListIterator<String> it = numbers.listIterator();
while (it.hasNext()) {
    System.out.println(it.nextIndex() + " " + it.next());
}

与Python一样,输出:

0 zero
1 one
2 two

答案 2

我发现这与python方法最相似。

用法

public static void main(String [] args) {
    List<String> strings = Arrays.asList("zero", "one", "two");
    for(EnumeratedItem<String> stringItem : ListUtils.enumerate(strings)) {
        System.out.println(stringItem.index + " " + stringItem.item);
    }
    System.out.println();
    for(EnumeratedItem<String> stringItem : ListUtils.enumerate(strings, 3)) {
        System.out.println(stringItem.index + " " + stringItem.item);
    }
}

输出

0 zero
1 one
2 two

3 zero
4 one
5 two

特征

  • 适用于任何可迭代
  • 不创建内存中列表副本(适用于大型列表)
  • 支持每种语法的本机
  • 接受可添加到索引的 start 参数

实现

import java.util.Iterator;

public class ListUtils {

    public static class EnumeratedItem<T> {
        public T item;
        public int index;

        private EnumeratedItem(T item, int index) {
            this.item = item;
            this.index = index;
        }
    }

    private static class ListEnumerator<T> implements Iterable<EnumeratedItem<T>> {

        private Iterable<T> target;
        private int start;

        public ListEnumerator(Iterable<T> target, int start) {
            this.target = target;
            this.start = start;
        }

        @Override
        public Iterator<EnumeratedItem<T>> iterator() {
            final Iterator<T> targetIterator = target.iterator();
            return new Iterator<EnumeratedItem<T>>() {

                int index = start;

                @Override
                public boolean hasNext() {
                    return targetIterator.hasNext();
                }

                @Override
                public EnumeratedItem<T> next() {
                    EnumeratedItem<T> nextIndexedItem = new EnumeratedItem<T>(targetIterator.next(), index);
                    index++;
                    return nextIndexedItem;
                }

            };
        }

    }

    public static <T> Iterable<EnumeratedItem<T>> enumerate(Iterable<T> iterable, int start) {
        return new ListEnumerator<T>(iterable, start);
    }

    public static <T> Iterable<EnumeratedItem<T>> enumerate(Iterable<T> iterable) {
        return enumerate(iterable, 0);
    }

}