是否可以在Java 8中强制转换流?

时间:2014-03-19 16:09:18

标签: java java-8 java-stream

是否可以在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>投射到Stream<Client>

请忽略这样的事实,即做这样的事情可能意味着糟糕的设计。我们在计算机科学课上做这样的事情,所以我正在研究java 8的新功能,如果可能的话,我很好奇。

4 个答案:

答案 0 :(得分:213)

我认为没有办法做到开箱即用。一个可能更清洁的解决方案是:

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);

答案 1 :(得分:13)

按照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);

答案 2 :(得分:9)

晚会,但我认为这是一个有用的答案。

flatMap是最简单的方法。

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

如果oClient,则使用单个元素创建Stream,否则使用空流。然后将这些流展平为Stream<Client>

答案 3 :(得分:5)

  

这看起来有点难看。是否可以将整个流转换为其他类型?喜欢将Stream<Object>投射到Stream<Client>

不,这是不可能的。这在Java 8中并不新鲜。这是泛型的。 List<Object>不是List<String>的超级类型,因此您不能仅将List<Object>投射到List<String>

这里的问题类似。您无法将Stream<Object>投射到Stream<Client>。当然你可以像这样间接地施展它:

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

但这不安全,可能会在运行时失败。其根本原因是Java中的泛型是使用擦除实现的。因此,没有关于它在运行时的Stream类型的类型信息。一切都只是Stream

顺便说一下,你的方法出了什么问题?看起来很好。