Lambda表达式的内部流程以及它如何识别参数类型。

huangapple go评论93阅读模式
英文:

Internal flow of lambda expression and how its identifies type of argument

问题

我已经创建了一个名为Movie的类,并且在集合排序方法中使用了lambda表达式。

类似于:

Collections.sort(movieList, (o1, o2) -> {
    return o1.getMoviesName().compareTo(o2.getMoviesName());
});

它能够正常工作,我很高兴看到这一点,但是当我试图理解它的结构时,我无法做到。lambda如何知道o1和o2参数是电影类型,因为我并没有说明o1和o2属于Movie对象。
请帮我理解lambda表达式的内部流程。因为大多数教程只提供语法和用法信息。

英文:

I have created class called Movie and while collections sort method I have used lambda expression.

Some thing like :

Collections.sort(movieList, (o1,o2)->{return o1.getMoviesName().compareTo(o2.getMoviesName());});

Its working fine and i am happy to see that but when I am trying to understand its structure i am unable to do that. how lambda find that o1 and o2 argumnet is type of movies because I haven't describe that o1 and o2 belong to Movie object.
Please help me to understand internal flow of lambda expression. As most tutorial only gives syntax and usage info only.

答案1

得分: 1

movieList必须在某处被声明为List<Movie>

因此,o1和o2的类型是Movie

编译器将会检查compareTo(Object other)是否是从movie.getMoviesName()(我假设这是一个String)可以访问的有效方法。

String实现了Comparable<String>,用于与另一个String进行比较。

以下是Collections.sort()的官方类型声明:

public static <T> void sort(List<T> list, Comparator<? super T> c)

// 在你的情况下,T = Movie,所以变为
public static void sort(List<Movie> list, Comparator<? super Movie> c)
// 你的Comparator将会处理Movie对象
英文:

movieList must be typed somewhere as a List&lt;Movie&gt;.
So o1 and o2 type is Movie.
The compiler will then check that compareTo(Object other) is a valid reachable method from movie.getMoviesName() which I assume is a String.
String implements Comparable&lt;String&gt; to compare with another String.
Here's the official type declaration of Collections.sort()

public static &lt;T&gt; void sort(List&lt;T&gt; list, Comparator&lt;? super T&gt; c)

// In your case T = Movie resulting in
public static void sort(List&lt;Movie&gt; list, Comparator&lt;? super Movie&gt; c)
// Your Comparator will treat Movie objects

答案2

得分: 1

如果你查看Collections.sort的代码,以及java.util中的任何代码,你会发现许多许多内容都涉及到了泛型泛型能够在编译时确保你使用了正确类型的对象。

如果你不使用Lambda,你的代码会类似于这样(以下是使用字符串的示例,但对于列表处理的任何对象,思想是相同的):

Collections.sort(strings, new Comparator<String>() {
    @Override
    public int compare(String o1, String o2) {
          return 0;
    }
};

在这个示例中,我提供了一个匿名类的Comparator接口实现,这是sort方法所需的,以便对输入集合进行排序。

正如你所看到的,内部java类Comparator中定义的泛型代码现在特定于我的列表类型,对我来说是String。这是编译器赋予你的这种可能性的作用(供参考,自Java 1.5以来添加了泛型,更多详情在这里)。

自Java 8以来,你可以用称为Lambda的东西替换这段丑陋的代码。你可以享受一个新的Java功能,以避免样板代码(即因技术要求而需要存在的代码,它增加了复杂性,并且由于技术细节而隐藏了代码的真正含义)。

与Lambda的等价物是这样的:

Collections.sort(strings, (s1, s2) -> s1.compareTo(s2));

在这里,即使你看不到参数,Java通过泛型和你的列表类型推断出你正在处理字符串。

供参考,只是为了让你知道,你还可以通过指定参数类型来提供Lambda(但不太常见):

Collections.sort(strings, (String s1, String s2) -> s1.compareTo(s2));
英文:

If you look into the code of the Collections.sort, and anywhere in the code of java.util, you will see that many many things are generics. Generics ensure at compile time that you are using the correct type of object.

If you were not using Lambda, your code would be similar to this (example with Strings, but the idea is the same for any object the List is dealing with):

Collections.sort(strings, new Comparator&lt;String&gt;() {
    @Override
    public int compare(String o1, String o2) {
          return 0;
    }
};

In this example, I've provided an implementation of the interface Comparator in the form of an anonymous class that the method sort needs in order to sort the input collection.

As you can see, the generics code that is defined in the internal java classes Comparator is now specific to the type of my list, in my case String. That is the role of the compiler to give you this possibility (For information, generics were added since Java 1.5, more here).

Since Java8, you can replace this hideous code with something call a lambda. You enjoy a new java feature to avoid boiler plate (i.e code that needs to be here but add complexity and hide the true meaning of your code because of technical requirements).

The equivalence with a Lambda is this:

Collections.sort(strings, (s1, s2) -&gt; s1.compareTo(s2));

Here, even if you don't see the parameter, Java guesses, thanks to generics and your list type that you are dealing with Strings.

For information, just so you know, you could also provide a lambda by specifying the parameter type (but no so common):

Collections.sort(strings, (String s1, String s2) -&gt; s1.compareTo(s2));

huangapple
  • 本文由 发表于 2020年8月25日 19:39:57
  • 转载请务必保留本文链接:https://go.coder-hub.com/63578053.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定