在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 staticfunction)…

您可以使用以下标准function的组合:

 StreamSupport.stream(Spliterators.spliteratorUnknownSize(CollectionUtils.toIterator(enumeration), Spliterator.IMMUTABLE), parallel) 

您还可以添加更多特征,如NONNULLDISTINCT

应用静态导入后,这将变得更可读:

 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()