IT TIP

Java 8에서 열거 형 반복

itqueen 2020. 10. 30. 21:22
반응형

Java 8에서 열거 형 반복


EnumerationLambda Expression을 사용하여 반복 할 수 있습니까? 다음 코드 조각의 Lambda 표현은 무엇입니까?

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

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

}

그 안에서 스트림을 찾지 못했습니다.


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기능에 유의 )…


(이 답변은 여러 옵션 중 하나를 보여줍니다. 수락 표시 있다고 해서 이것이 최선의 선택임을 의미하지는 않습니다. 다른 답변을 읽고 현재 상황에 따라 하나를 선택하는 것이 좋습니다. IMO : -for
Java 8 Holger 's answer 간단한 것 외에도 내 솔루션에서 발생하는 추가 반복이 필요하지 않기 때문에 가장 좋습니다
.- Java 9의 경우 Tagir Valeev 답변 에서 솔루션을 선택합니다 )


당신은 당신의 요소를 복사 할 수 있습니다 EnumerationArrayListCollections.list다음처럼 사용

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

코드 Enumeration 이 많이 있는 경우 EnumerationStream 으로 변환하는 정적 도우미 메서드를 만드는 것이 좋습니다 . 정적 메서드는 다음과 같습니다.

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의 솔루션과 달리 다른 스트림 작업의 이점을 누릴 수 있으므로 기존 코드를 더욱 간단하게 만들 수 있습니다. 다음은 그 예입니다.

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

Java-9 이후 Enumeration.asIterator()순수한 Java 솔루션을 더 간단하게 만드는 새로운 기본 방법이 있습니다 .

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

다음과 같은 표준 기능 조합을 사용할 수 있습니다.

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

당신은 또한 같은 많은 특성을 추가 할 수있다 NONNULLDISTINCT.

정적 가져 오기를 적용하면 더 읽기 쉬워집니다.

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

이제 어떤 방식 으로든 사용할 수있는 표준 Java 8 스트림이 생겼습니다! true병렬 처리를 위해 통과 할 수 있습니다 .

Enumeration에서 Iterator로 변환하려면 다음 중 하나를 사용하십시오.

  • CollectionUtils.toIterator() Spring 3.2에서 또는 사용할 수 있습니다.
  • IteratorUtils.asIterator() Apache Commons Collections 3.2에서
  • Iterators.forEnumeration() Google Guava에서

Java 8의 경우 열거 형을 스트림으로 변환하는 가장 간단한 방법은 다음과 같습니다.

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


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:

 /**
 * 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();
        }
    };
}

참고URL : https://stackoverflow.com/questions/23261803/iterate-an-enumeration-in-java-8

반응형