[java] Java 8에서 스트림을 캐스트 할 수 있습니까?

Java 8에서 스트림을 캐스트 할 수 있습니까? 객체 목록이 있다고 가정하면 추가 객체를 모두 필터링하기 위해 이와 같은 작업을 수행 할 수 있습니다.

Stream.of(objects).filter(c -> c instanceof Client)

이 후, 고객과 무언가를하고 싶다면 각각을 캐스팅해야합니다.

Stream.of(objects).filter(c -> c instanceof Client)
    .map(c -> ((Client) c).getID()).forEach(System.out::println);

조금 추한 것 같습니다. 전체 스트림을 다른 유형으로 캐스트 할 수 있습니까? 마찬가지로 캐스팅 Stream<Object>A를 Stream<Client>?

이와 같은 작업을 수행하면 디자인이 잘못 될 수 있다는 사실을 무시하십시오. 우리는 내 컴퓨터 과학 수업에서 이와 같은 작업을 수행하므로 Java 8의 새로운 기능을 살펴 보았으며 이것이 가능한지 궁금했습니다.



답변

나는 그것을 즉시 할 수있는 방법이 없다고 생각합니다. 더 깨끗한 해결책은 다음과 같습니다.

Stream.of(objects)
    .filter(c -> c instanceof Client)
    .map(c -> (Client) c)
    .map(Client::getID)
    .forEach(System.out::println);

또는 의견에서 제안한 것처럼 cast방법을 사용할 수 있습니다. 전자는 읽기가 더 쉬울 수 있습니다.

Stream.of(objects)
    .filter(Client.class::isInstance)
    .map(Client.class::cast)
    .map(Client::getID)
    .forEach(System.out::println);


답변

ggovan ‘s answer 라인을 따라 다음과 같이하십시오.

/**
 * Provides various high-order functions.
 */
public final class F {
    /**
     * When the returned {@code Function} is passed as an argument to
     * {@link Stream#flatMap}, the result is a stream of instances of
     * {@code cls}.
     */
    public static <E> Function<Object, Stream<E>> instancesOf(Class<E> cls) {
        return o -> cls.isInstance(o)
                ? Stream.of(cls.cast(o))
                : Stream.empty();
    }
}

이 헬퍼 기능 사용 :

Stream.of(objects).flatMap(F.instancesOf(Client.class))
        .map(Client::getId)
        .forEach(System.out::println);


답변

파티에 늦었지만 유용한 답변이라고 생각합니다.

flatMap 가장 짧은 방법입니다.

Stream.of(objects).flatMap(o->(o instanceof Client)?Stream.of((Client)o):Stream.empty())

경우 oA는 Client다음 그렇지 않으면 빈 스트림을 사용, 하나의 요소 스트림을 생성합니다. 그런 다음이 개울은로 편평 해집니다 Stream<Client>.


답변

조금 추한 것 같습니다. 전체 스트림을 다른 유형으로 캐스트 할 수 있습니까? 마찬가지로 캐스팅 Stream<Object>A를 Stream<Client>?

불가능합니다. 이것은 Java 8의 새로운 기능이 아닙니다. 이것은 제네릭에만 해당됩니다. A는 List<Object>의 슈퍼 유형이 아닌 List<String>당신이 단지를 캐스팅 할 수 있도록 List<Object>A를List<String> .

여기서도 비슷한 문제입니다. 당신은 캐스트 수 없습니다 Stream<Object>Stream<Client>. 물론 다음과 같이 간접적으로 캐스팅 할 수 있습니다.

Stream<Client> intStream = (Stream<Client>) (Stream<?>)stream;

그러나 그것은 안전하지 않으며 런타임에 실패 할 수 있습니다. 그 이유는 Java의 제네릭이 삭제를 사용하여 구현되기 때문입니다. 따라서 어떤 유형의 Stream런타임에 사용 가능한 유형 정보가 없습니다 . 모든 것이 단지Stream 입니다.

BTW, 당신의 접근 방식에 어떤 문제가 있습니까? 나에게 잘 보인다.


답변