在Java 8中迭代枚举
是否有可能通过使用Lambdaexpression式迭代Enumeration
? 以下代码片段的Lambda表示是什么:
Enumeration<NetworkInterface> nets = NetworkInterface.getNetworkInterfaces(); while (nets.hasMoreElements()) { NetworkInterface networkInterface = nets.nextElement(); }
我没有发现任何stream。
(这个答案显示了其中的一个选项,因为被OP接受了,并不意味着它是最好的,我build议阅读其他的答案,根据你所处的情况select一个答案。我个人觉得Holger的答案最好,因为简单并没有额外的迭代 – 发生在我的解决scheme)
您可以使用Collections.list
将元素从Enumeration复制到ArrayList
,然后像使用它一样
Collections.list(yourEnumeration).forEach(yourAction);
如果代码中有很多枚举 ,我build议创build一个静态帮助器方法,将枚举转换为一个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); }
使用静态导入的方法。 与Holger的解决scheme相反,您可以从不同的stream操作中受益,这可能会使现有的代码变得更简单。 这里是一个例子:
Map<...> map = enumerationAsStream(enumeration) .filter(Objects::nonNull) .collect(groupingBy(...));
由于Java-9将会有新的默认方法Enumeration.asIterator()
,这将使纯Java解决scheme变得更简单:
nets.asIterator().forEachRemaining(iface -> { ... });
如果您不喜欢在迭代开始之前Collections.list(Enumeration)
将整个内容复制到(临时)列表的事实,则可以使用简单的实用程序方法来帮助您:
public static <T> void forEachRemaining(Enumeration<T> e, Consumer<? super T> c) { while(e.hasMoreElements()) c.accept(e.nextElement()); }
那么你可以简单地做forEachRemaining(enumeration, lambda-expression);
(介意import static
function)…
您可以使用以下标准function的组合:
StreamSupport.stream(Spliterators.spliteratorUnknownSize(CollectionUtils.toIterator(enumeration), Spliterator.IMMUTABLE), parallel)
您还可以添加更多特征,如NONNULL
或DISTINCT
。
应用静态导入后,这将变得更可读:
stream(spliteratorUnknownSize(toIterator(enumeration), IMMUTABLE), false)
现在你有了一个标准的Java 8 Stream来以任何方式使用! 你可以通过并行处理。
要从Enumeration转换为Iterator,请使用以下任何一个:
- 可以使用Spring 3.2的
CollectionUtils.toIterator()
- Apache Commons Collections 3.2中的
IteratorUtils.asIterator()
- 来自Google Guava的
Iterators.forEnumeration()