英文:
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<Movie>
.
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<String>
to compare with another String.
Here's the official type declaration of Collections.sort()
public static <T> void sort(List<T> list, Comparator<? super T> c)
// In your case T = Movie resulting in
public static void sort(List<Movie> list, Comparator<? super Movie> 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<String>() {
@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) -> 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) -> s1.compareTo(s2));
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论