2

我正在玩 Java 8 和 e(fx)clipse,只是尝试一下。我正在尝试应用一个从可为空字符串中删除所有 a 的映射函数。但是,随后的过滤器函数存在编译错误,因为 map 返回Optional<Object>而不是Optional<String>.

我究竟做错了什么?

Optional.ofNullable(string)
    .map( s -> s.replaceAll("a", "") )
    .filter( s -> !((String) s).isEmpty() ) //notice the need for cast
    .map( s -> "String: " + s )
    .ifPresent(System.out::println);
4

2 回答 2

4

似乎是类型推断的问题。Optional.map接受一个类型的参数Function<? super T, ? extend U>并返回一个Optional<U>.

现在String,类型T被推断为String,并且U被推断为Object,这就是它返回的原因Optional<Object>。我没有过多地使用 Java 8,但我想这就是正在发生的事情。

您可以Optional<String>通过给出显式类型参数来获得:

Optional.ofNullable(string).<String>map(s -> s.replaceAll("a", ""))
    .filter(s -> s.isEmpty())
    .map(s -> "String" + s)
    .ifPresent(System.out::println);

<String>.和之间map(...)表示一个显式类型参数,以确保类型参数U被推断为String.

坦率地说,我本来希望在没有显式类型参数的情况下工作,因为Function传递给map的输入和输出类型都为String

s (type is String) -> s.replaceAll(..) (this also returns String)

并且因为,String同时满足边界 -? extends T? super U. 记住在泛型中,String super String并且String extends Stringtrue. 所以,我很惊讶为什么它没有按预期工作。但同样,对于这些惊喜,我猜,Java 有明确的类型参数

注意:所以原来是eclipse的问题。原始代码在命令行上运行良好。


Function<T, R>另一种选择是预先创建一个对象,然后传递它:

Function<String, String> func = s -> s.replaceAll("a", "");

Optional.ofNullable(string).map(func)
    .filter(s -> s.isEmpty())
    .map(s -> "String" + s)
    .ifPresent(System.out::println);

参考:

于 2013-10-13T08:31:11.017 回答
3

看来您的问题已在以后的 Java 8 版本中得到解决,因为这对我来说编译时没有错误:

public static void main(String[] args) {
    Optional.ofNullable("x")
            .map(s -> s.replaceAll("a","b"))
            .filter(s -> !s.isEmpty());
}

我的Java版本:

$ java -version

java version "1.8.0-ea"
Java(TM) SE Runtime Environment (build 1.8.0-ea-b108)
Java HotSpot(TM) 64-Bit Server VM (build 25.0-b50, mixed mode)

请注意,如果您在 Eclipse 中看到错误,则 Java JDK 内部版本号无关紧要,因为 Eclipse 使用自己的 Java 编译器。尝试javac从命令行编译你的类。

于 2013-10-13T09:23:20.413 回答