简体   繁体   English

Java Lambda表达式语法的清晰度-省略参数数据类型

[英]Clarity on syntax of Java lambda expressions - omit parameter data type

In this official Oracle tutorial: https://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html 在此官方Oracle教程中: https : //docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html

Under the Syntax of Lambda Expressions, it explicitly states: "Note: You can omit the data type of the parameters in a lambda expression." 在Lambda表达式的语法下,它明确指出:“注意:您可以省略lambda表达式中参数的数据类型。”

It does not say "often" or "frequently", it reads as though you can categorically always do this. 它不会说“经常”或“经常”,而是显示您可以绝对始终执行此操作。 Can someone clarify this matter for me and either state whether that statement made by Oracle is correct or not. 有人可以帮我澄清一下这件事吗,或者说明Oracle所作的陈述是否正确。 If it is not then it's pretty bad coming from Oracle themselves, but it would be nice to see a couple of examples of circumstances when the parameter types cannot be inferred. 如果不是这样,那么来自Oracle本身就很糟糕,但是很高兴看到几个无法推断参数类型的情况的例子。

This means that under most situations, the compiler automatically sees what you arguments are, for example: 这意味着在大多数情况下,编译器会自动查看您的参数,例如:

Stream.of(new Object())
    .map(o -> o.toString())
    .map(o -> o.toCharArray())
    .flatMap(o -> Arrays.stream(o))
    .foreach(o -> System.out.println(o));

While we give no hints to the parameters of the lamba expressions, the compiler will see the following types for the arguments: 虽然我们没有暗示lamba表达式的参数,但编译器将看到以下类型的参数:

Stream.of(new Object())
    .map((Object o) -> o.toString())
    .map((String o) -> o.toCharArray())
    .flatMap((char[] o) -> Arrays.stream(o))
    .foreach((char o) -> System.out.println(o));

Both versions compile correctly under the java 8 compiler. 这两个版本都可以在Java 8编译器下正确编译。


There are also moment when the compiler cannot do this, this happens when you walk against the limitations of the compiler, the following example is posted by Alexis C : 在某些情况下,编译器无法执行此操作,这是在您违反编译器的限制时发生的,以下示例由Alexis C发布:

Stream.of(new SimpleEntry<>("a", 1)).sorted(
       Comparator.comparing(s -> s.getKey()).reversed())

In this example, the knows sorted( requires a Comparator<? super SimpleEntry> , but gets confused by the call to Comparator.reversed() because the return type of that method is affected by the input, while a lamba usually looks ahead to see what type it must transform in. By "unnaking" the lamba, we force it to become our wanted result. 在此示例中,知道sorted(需要Comparator<? super SimpleEntry> ,但是由于对Comparator.reversed()的调用而感到困惑,因为该方法的返回类型受输入的影响,而lamba通常会向前看它必须转换为哪种类型。通过“取消隐藏”兰巴,我们迫使它成为我们想要的结果。

Stream.of(new SimpleEntry<>("a", 1)).sorted(
       Comparator.comparing((Map.Entry<String, Integer> s) -> s.getKey()).reversed())

This bug happens in all situations where these conflicting look-ahead and look-behind systems are used, another example I created: 在使用这些相互矛盾的先行和后进系统的所有情况下都会发生此错误,这是我创建的另一个示例:

public static void main(String ... args) {
    Function<Number, char[]> func = 
       convert(o->o.toString(), o->o.toCharArray()).andThen(Function.identity());
}

public static <A, B, C> Function<A, C> convert(Function<A, B> c1, Function<B, C> c2) {
    return t -> c2.apply(c1.apply(t));
}

The above fails to compile, until we make this of it: 上面的代码无法编译,直到我们使用它:

public static void main(String ... args) {
    Function<Number, char[]> func = 
       convert((Number o)->o.toString(), o->o.toCharArray()).andThen(Function.identity());
}

public static <A, B, C> Function<A, C> convert(Function<A, B> c1, Function<B, C> c2) {
    return t -> c2.apply(c1.apply(t));
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM