source

Java 8에서 Stream을 캐스팅할 수 있습니까?

factcode 2022. 8. 20. 18:36
반응형

Java 8에서 Stream을 캐스팅할 수 있습니까?

자바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>에 대해서Stream<Client>?

이런 짓을 하면 디자인이 나빠질 수 있으니 무시해 주세요.컴퓨터 사이언스 수업 시간에 이런 걸 해서 자바8의 새로운 기능을 알아보고 이게 가능한지 궁금했어요

나는 그것을 바로 할 수 있는 방법이 없다고 생각한다.보다 깔끔한 솔루션은 다음과 같습니다.

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

또는 댓글에 제시된 바와 같이castmethod - 단, 전자가 읽기 쉬울 수 있습니다.

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

ggovan의 대답에 따라서, 나는 이것을 다음과 같이 한다.

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

한다면o는 입니다.Client그런 다음 단일 요소로 스트림을 만들거나, 그렇지 않으면 빈 스트림을 사용합니다.이 스트림들은 그 후 평탄하게 됩니다.Stream<Client>.

이거 좀 못생겼어.전체 스트림을 다른 형식으로 캐스팅할 수 있습니까?출연자처럼Stream<Object>에 대해서Stream<Client>?

아니, 그건 불가능할 거야.이것은 Java 8에서는 새로운 것이 아닙니다.이것은 제네릭에 특유합니다.aList<Object>슈퍼 타입이 아니다List<String>그래서 그냥 캐스트를 하면 안 돼요.List<Object>에 대해서List<String>.

여기서도 비슷한 문제가 있다.섭외가 안 돼요.Stream<Object>로.Stream<Client>물론 이렇게 간접적으로 캐스팅할 수 있습니다.

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

그러나 이는 안전하지 않으며 런타임에 실패할 수 있습니다.그 근본적인 이유는 Java의 범용성이 삭제를 사용하여 구현되기 때문입니다.따라서 어떤 타입의 타입을 사용할 수 있는지 알 수 있는 정보는 없습니다.Stream실행 시입니다.모든 것이 그저Stream.

그나저나, 네 접근 방식이 뭐가 문제야?나한테는 괜찮아 보이는데요.

한 클래스의 유형화되지 않은 컬렉션을 처리할 때 다음과 같이 유형화 컬렉션을 만들 수 있습니다.

UntypedObjCollection bag = some preGenerics method;
List<Foo> foolist = new ArrayList<>();
bag.stream().forEach(o ->fooList.add((Foo)o));

오브젝트를 무언가에 캐스팅하고 필터링, 지도 등을 할 수 있는 방법은 없는 것 같습니다.한 방에오브젝트를 유형화된 컬렉션에 포함시키는 유일한 방법은 터미널 작업입니다.이것은 JDK 17을 실행하고 있으며 보다 세분화된 메서드를 시도할 때 module.base 예외를 처리합니다.

언급URL : https://stackoverflow.com/questions/22511750/is-it-possible-to-cast-a-stream-in-java-8

반응형