Tap*_*ose 70 java iteration lambda enumeration java-8
是否可以Enumeration
使用Lambda Expression 进行迭代?以下代码片段的Lambda表示形式是什么:
Enumeration<NetworkInterface> nets = NetworkInterface.getNetworkInterfaces();
while (nets.hasMoreElements()) {
NetworkInterface networkInterface = nets.nextElement();
}
Run Code Online (Sandbox Code Playgroud)
我没有在其中找到任何流.
Psh*_*emo 86
(这个答案显示了很多选项中的一个.只是因为它有接受标记,并不意味着它是最好的.我建议阅读其他答案并根据你所处的情况选择一个.就个人而言,我发现Holger的答案最好的,因为它也很简单,但不需要额外的迭代 - 这在我的解决方案中发生.但对于Java 9解决方案,请访问Tagir Valeev回答)
您可以将元素从您复制Enumeration
到ArrayList
,Collections.list
然后使用它
Collections.list(yourEnumeration).forEach(yourAction);
Run Code Online (Sandbox Code Playgroud)
nos*_*sid 51
如果代码中有很多Enumerations,我建议创建一个静态帮助器方法,将Enumeration转换为Stream.静态方法可能如下所示:
public static <T> Stream<T> enumerationAsStream(Enumeration<T> e) {
return StreamSupport.stream(
Spliterators.spliteratorUnknownSize(
new Iterator<T>() {
public T next() {
return e.nextElement();
}
public boolean hasNext() {
return e.hasMoreElements();
}
},
Spliterator.ORDERED), false);
}
Run Code Online (Sandbox Code Playgroud)
将该方法与静态导入一起使用.与Holger的解决方案相比,您可以从不同的流操作中受益,这可能使现有代码更简单.这是一个例子:
Map<...> map = enumerationAsStream(enumeration)
.filter(Objects::nonNull)
.collect(groupingBy(...));
Run Code Online (Sandbox Code Playgroud)
Tag*_*eev 45
从Java-9开始,将有一个新的默认方法Enumeration.asIterator()
,它将使纯Java解决方案更简单:
nets.asIterator().forEachRemaining(iface -> { ... });
Run Code Online (Sandbox Code Playgroud)
Hol*_*ger 34
如果您不喜欢在Collections.list(Enumeration)
迭代开始之前将整个内容复制到(临时)列表中的事实,您可以使用一个简单的实用方法来帮助自己:
public static <T> void forEachRemaining(Enumeration<T> e, Consumer<? super T> c) {
while(e.hasMoreElements()) c.accept(e.nextElement());
}
Run Code Online (Sandbox Code Playgroud)
然后你可以简单地做forEachRemaining(enumeration, lambda-expression);
(注意import static
功能)......
Arn*_*ter 11
您可以使用以下标准功能组合:
StreamSupport.stream(Spliterators.spliteratorUnknownSize(CollectionUtils.toIterator(enumeration), Spliterator.IMMUTABLE), parallel)
Run Code Online (Sandbox Code Playgroud)
您还可以添加更多的特征,如NONNULL
或DISTINCT
.
应用静态导入后,这将变得更具可读性:
stream(spliteratorUnknownSize(toIterator(enumeration), IMMUTABLE), false)
Run Code Online (Sandbox Code Playgroud)
现在你有一个标准的Java 8 Stream以任何方式使用!您可以通过true
并行处理.
要从Enumeration转换为Iterator,请使用以下任意一项:
CollectionUtils.toIterator()
从Spring 3.2或者你可以使用IteratorUtils.asIterator()
来自Apache Commons Collections 3.2Iterators.forEnumeration()
来自Google Guava对于Java 8,枚举到流的最简单的转换是:
Collections.list(NetworkInterface.getNetworkInterfaces()).stream()
我知道这是一个老问题,但我想提出 Collections.asList 和 Stream 功能的替代方案。由于问题的标题是“迭代枚举”,我认识到有时您想要使用 lambda 表达式,但增强的 for 循环可能更可取,因为枚举对象可能会抛出异常,并且 for 循环更容易封装在更大的 try 中 - catch 代码段(lambda 要求在 lambda 内捕获已声明的异常)。为此,这里使用 lambda 创建一个可在 for 循环中使用的 Iterable,并且不会预加载枚举:
/**
* Creates lazy Iterable for Enumeration
*
* @param <T> Class being iterated
* @param e Enumeration as base for Iterator
* @return Iterable wrapping Enumeration
*/
public static <T> Iterable<T> enumerationIterable(Enumeration<T> e)
{
return () -> new Iterator<T>()
{
@Override
public T next()
{
return e.nextElement();
}
@Override
public boolean hasNext()
{
return e.hasMoreElements();
}
};
}
Run Code Online (Sandbox Code Playgroud)