在 Java 8 中迭代枚举

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/23261803/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 21:33:46  来源:igfitidea点击:

Iterate an Enumeration in Java 8

javalambdaiterationenumerationjava-8

提问by Tapas Bose

Is it possible to iterate an Enumerationby using Lambda Expression? What will be the Lambda representation of the following code snippet:

是否可以Enumeration使用 Lambda 表达式进行迭代?以下代码片段的 Lambda 表示是什么:

Enumeration<NetworkInterface> nets = NetworkInterface.getNetworkInterfaces();

while (nets.hasMoreElements()) {
    NetworkInterface networkInterface = nets.nextElement();

}

I didn't find any stream within it.

我没有在其中找到任何流。

采纳答案by Holger

In case you don't like the fact that Collections.list(Enumeration)copies the entire contents into a (temporary) list before the iteration starts, you can help yourself out with a simple utility method:

如果您不喜欢在Collections.list(Enumeration)迭代开始之前将整个内容复制到(临时)列表中的事实,您可以使用一个简单的实用方法来帮助自己:

public static <T> void forEachRemaining(Enumeration<T> e, Consumer<? super T> c) {
  while(e.hasMoreElements()) c.accept(e.nextElement());
}

Then you can simply do forEachRemaining(enumeration, lambda-expression);(mind the import staticfeature)…

然后你可以简单地做forEachRemaining(enumeration, lambda-expression);(注意这个import static功能)......

回答by Pshemo

(This answer shows one of many options. Just because is hashad acceptance mark, doesn't mean it is the best one. I suggest reading other answers and picking one depending on situation you are in. IMO:
- for Java 8 Holger's answeris nicest, because aside from being simple it doesn't require additional iteration which happens in mine solution.
- for Java 9 I would pick solution from Tagir Valeev answer)

(这个答案显示了许多选项之一。仅仅因为它接受标记,并不意味着它是最好的。我建议阅读其他答案并根据您所处的情况选择一个。IMO:
-对于 Java 8 Holger 的答案是最好的,因为除了简单之外,它不需要在我的解决方案中发生的额外迭代。
- 对于 Java 9,我会从Tagir Valeev 答案中选择解决方案)



You can copy elements from your Enumerationto ArrayListwith Collections.listand then use it like

你可以从你的元素复制EnumerationArrayListCollections.list,然后使用它像

Collections.list(yourEnumeration).forEach(yourAction);

回答by nosid

If there are a lot of Enumerationsin your code, I recommend creating a static helper method, that converts an Enumerationinto a Stream. The static method might look as follows:

如果您的代码中有很多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);
}

Use the method with a static import. In contrast to Holger's solution, you can benefit from the different streamoperations, which might make the existing code even simpler. Here is an example:

将该方法与静态导入一起使用。与 Holger 的解决方案相比,您可以从不同的操作中受益,这可能会使现有代码更加简单。下面是一个例子:

Map<...> map = enumerationAsStream(enumeration)
    .filter(Objects::nonNull)
    .collect(groupingBy(...));

回答by Arne Burmeister

You can use the following combination of standard functions:

您可以使用以下标准功能组合:

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

You may also add more characteristics like NONNULLor DISTINCT.

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

After applying static imports this will become more readable:

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

stream(spliteratorUnknownSize(toIterator(enumeration), IMMUTABLE), false)

now you have a standard Java 8 Stream to be used in any way! You may pass truefor parallel processing.

现在您拥有了一个可以以任何方式使用的标准 Java 8 Stream!您可以通过true并行处理。

To convert from Enumeration to Iterator use any of:

要将枚举转换为迭代器,请使用以下任一方法:

  • CollectionUtils.toIterator()from Spring 3.2 or you can use
  • IteratorUtils.asIterator()from Apache Commons Collections 3.2
  • Iterators.forEnumeration()from Google Guava
  • CollectionUtils.toIterator()从 Spring 3.2 或者你可以使用
  • IteratorUtils.asIterator()来自 Apache Commons Collections 3.2
  • Iterators.forEnumeration()来自谷歌番石榴

回答by Tagir Valeev

Since Java-9 there will be new default method Enumeration.asIterator()which will make pure Java solution simpler:

由于 Java-9 将有新的默认方法Enumeration.asIterator(),这将使纯 Java 解决方案更简单:

nets.asIterator().forEachRemaining(iface -> { ... });

回答by Marek Gregor

For Java 8 the simplest transformation of enumeration to stream is:

对于 Java 8,枚举到流的最简单转换是:

Collections.list(NetworkInterface.getNetworkInterfaces()).stream()

Collections.list(NetworkInterface.getNetworkInterfaces()).stream()

回答by user579013

I know this is an old question but I wanted to present an alternative to Collections.asList and Stream functionality. Since the question is titled "Iterate an Enumeration", I recognize sometimes you want to use a lambda expression but an enhanced for loop may be preferable as the enumerated object may throw an exception and the for loop is easier to encapsulate in a larger try-catch code segment (lambdas require declared exceptions to be caught within the lambda). To that end, here is using a lambda to create an Iterable which is usable in a for loop and does not preload the enumeration:

我知道这是一个老问题,但我想提出 Collections.asList 和 Stream 功能的替代方案。由于问题的标题是“迭代枚举”,我认识到有时您想使用 lambda 表达式,但增强的 for 循环可能更可取,因为枚举对象可能会引发异常并且 for 循环更容易封装在更大的 try- 中 -捕获代码段(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();
        }
    };
}