将 Enumeration<T> 视为 Iterator<T>

16

我有一个实现了 Enumeration<T> 接口的类,但是 Java 的 foreach 循环需要 Iterator<T> 接口。Java 标准库中是否有 EnumerationIterator 的适配器?


最好不要使用枚举器作为它是一个遗留类,或者不要使用“增强”的 for each 循环,这样会更简单。 - Peter Lawrey
5
for-each循环需要一个Iterable而不是Iterator,你真正想要的是哪个? - Michael Myers
7个回答

34

如果您只需要在for-each循环中迭代某些内容(因此需要一个Iterable而不仅仅是一个Iterator),始终可以使用java.util.Collections.list(Enumeration<T> e)(不使用任何外部库)。


2
这是一个简单的答案,使用专门为此目的设计的标准Java类/方法。 - aeropapa17

12
您需要一个所谓的“适配器”,将Enumeration适配到与之不兼容的Iterator。Apache commons-collections 提供了EnumerationIterator。使用方法如下:
Iterator iterator = new EnumerationIterator(enumeration);

1
这是回答问题的原因,因为你不能在foreach循环中使用迭代器。 - Edward Q. Bridges

7

a) 我相信你的意思是Enumeration,而不是Enumerator
b) Guava提供了一个帮助方法Iterators.forEnumeration(enumeration),可以从枚举中生成迭代器,但这对你没有帮助,因为你需要一个Iterable(迭代器的提供者),而不是一个Iterator
c) 你可以使用这个辅助类来实现:

public class WrappingIterable<E> implements Iterable<E>{
    private Iterator<E> iterator;

    public WrappingIterable(Iterator<E> iterator){
        this.iterator = iterator;
    }

    @Override
    public Iterator<E> iterator(){
        return iterator;
    }
}

现在你的客户端代码应该像这样:

for(String string : new WrappingIterable<String>(
                        Iterators.forEnumeration(myEnumeration))){
    // your code here            
}

但这值得付出这样的努力吗?

你可以让你的包装器构造函数接受一个枚举。 - Thorbjørn Ravn Andersen
3
请注意,“Iterable”表示您可以重复请求迭代器。但此包装程序不符合此规定。 - Thorbjørn Ravn Andersen

3
不需要自己动手。看看谷歌的Guava库。具体来说:
Iterators.forEnumeration()

1
那将会生成一个迭代器(Iterator),而不是可迭代对象(Iterable)。 - Thorbjørn Ravn Andersen
@ThorbjørnRavnAndersen - OP 明确要求从枚举到迭代器的适配器。他没有要求从枚举到可迭代对象的适配器。 - rfeak
2
他想在foreach中使用它,因此Iterator是一个打字错误。 - Thorbjørn Ravn Andersen

2

标准库中没有适配器可用。不幸的是,您必须编写自己的适配器。其他人已经有了一些示例,例如:

IterableEnumerator


1
是的,标准库中有专门用于此目的的内容:Collections.list - aeropapa17

1

或者在commons-collections中使用EnumerationUtils

import static org.apache.commons.collections.EnumerationUtils.toList

toList(myEnumeration)

0

如果你可以修改这个类,那么你可以简单地实现 Iterator<T> 并添加 remove 方法。


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