programing

Java 8 JDK를 사용하여 Itable을 스트림으로 변환

prostudy 2022. 5. 31. 07:45
반응형

Java 8 JDK를 사용하여 Itable을 스트림으로 변환

인터페이스를 가지고 있어java.lang.Iterable<T>.

저는 Java 8 Stream API를 사용하여 그 결과를 조작하고 싶습니다.

그러나 Itable은 "스트리밍"을 할 수 없다.

Itable을 List로 변환하지 않고 스트림으로 사용할 수 있는 방법을 알고 계십니까?

이 문제를 해결하는 것보다 훨씬 더 좋은 답이 있습니다.spliteratorUnknownSize더 쉽고 더 나은 결과를 얻을 수 있습니다. Iterable가 있다spliterator()방법론이죠, 그러니 그냥 스플리터를 구하는데 사용하세요.최악의 경우 동일한 코드입니다(기본 구현에서는spliteratorUnknownSize하지만 더 일반적인 경우에서는Iterable는 이미 컬렉션이기 때문에 더 나은 스플리터를 얻을 수 있기 때문에 스트림 퍼포먼스가 향상됩니다(아마도 좋은 병행).또한 코드도 적습니다.

StreamSupport.stream(iterable.spliterator(), false)
             .filter(...)
             .moreStreamOps(...);

보다시피, 스트림을 받는 것은Iterable(이 질문도 참조)는 그다지 고통스럽지 않습니다.

Guava 라이브러리를 사용할 수 있다면 버전 21부터 사용할 수 있습니다.

Streams.stream(iterable)

쉽게 작성할 수 있습니다.Stream갑자기Iterable또는Iterator:

public static <T> Stream<T> stream(Iterable<T> iterable) {
    return StreamSupport.stream(
        Spliterators.spliteratorUnknownSize(
            iterable.iterator(),
            Spliterator.ORDERED
        ),
        false
    );
}

Guava는 다음과 같은 방법으로 이를 지원하고 있습니다.

Streams.stream(iterable);

이 구현은 다른 답변과 약간 다른 작업을 수행한다는 점을 강조하고 싶습니다.이 경우,Iterable종류Collection캐스팅을 해주시죠.

public static <T> Stream<T> stream(Iterable<T> iterable) {
  return (iterable instanceof Collection)
    ? ((Collection<T>) iterable).stream()
    : StreamSupport.stream(iterable.spliterator(), false);
}

public static <T> Stream<T> stream(Iterator<T> iterator) {
  return StreamSupport.stream(
    Spliterators.spliteratorUnknownSize(iterator, 0),
    false
  );
}

나는 JOOL 라이브러리를 사용하는 것을 제안하고 싶다. 그것은 스플리터 마법을 뒤에 숨긴다.Seq.seq(iterable)전화 및 기타 많은 유용한 기능을 제공합니다.

이 클래스를 만들었습니다.

public class Streams {
    /**
     * Converts Iterable to stream
     */
    public static <T> Stream<T>  streamOf(final Iterable<T> iterable) {
        return toStream(iterable, false);
    }

    /**
     * Converts Iterable to parallel stream
     */
    public static <T> Stream<T> parallelStreamOf(final Iterable<T> iterable) {
        return toStream(iterable, true);
    }

    private static <T> Stream<T> toStream(final Iterable<T> iterable, final boolean isParallel) {
        return StreamSupport.stream(iterable.spliterator(), isParallel);
    }
}

스플리터나 부울(isParallel)에 대해 생각할 필요가 없기 때문에 완벽하게 읽을 수 있다고 생각합니다.

이 문제에 대한 매우 간단한 회피책은Streamable<T>인터페이스 확장Iterable<T>이 들어 있는 것은default <T> stream()방법.

interface Streamable<T> extends Iterable<T> {
    default Stream<T> stream() {
        return StreamSupport.stream(spliterator(), false);
    }
}

이제 여러분 중 누구라도Iterable<T>는 선언하는 것만으로 스트림 가능하게 할 수 있습니다.implements Streamable<T>대신Iterable<T>.

Vavr(이전의 Javaslang)을 사용하는 경우는, 다음과 같이 간단하게 실시할 수 있습니다.

Iterable i = //...
Stream.ofAll(i);

언급URL : https://stackoverflow.com/questions/23932061/convert-iterable-to-stream-using-java-8-jdk

반응형