Java 如何从方法引用创建比较器?
我正在学习lambda表达式。我不明白比较器是如何从方法引用返回的 我想按年龄对一份名单进行排序 要做到这一点,我有一种方法来找出年龄差异:Java 如何从方法引用创建比较器?,java,lambda,Java,Lambda,我正在学习lambda表达式。我不明白比较器是如何从方法引用返回的 我想按年龄对一份名单进行排序 要做到这一点,我有一种方法来找出年龄差异: public int ageDifference(final Person other) { return age - other.age; } 排序的方法需要一个比较器作为参数 Stream<T> sorted(Comparator<? super T> comparator); 如何在比较器中转换Person::ag
public int ageDifference(final Person other) {
return age - other.age;
}
排序的方法需要一个比较器作为参数
Stream<T> sorted(Comparator<? super T> comparator);
如何在比较器中转换Person::ageDifference
我的完整示例:
public class Person {
private final String name;
private final int age;
public Person(final String theName, final int theAge) {
name = theName;
age = theAge;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
public int ageDifference(final Person other) {
return age - other.age;
}
public String toString() {
return String.format("%s - %d", name, age);
}
public static void main (String args[] ){
final List<Person> people = Arrays.asList(
new Person("John", 10),
new Person("Greg", 30),
new Person("Sara", 20),
new Person("Jane", 15));
List<Person> ascendingAge =
people.stream()
.sorted(Person::ageDifference)
.collect(toList());
System.out.println(ascendingAge);
}
}
公共类人物{
私有最终字符串名;
私人最终年龄;
公众人物(最终字符串名称、最终内页){
名称=名称;
年龄=年龄;
}
公共字符串getName(){
返回名称;
}
公共整数getAge(){
回归年龄;
}
公众智力差异(最终个人其他){
返回年龄-其他年龄;
}
公共字符串toString(){
返回字符串。格式(“%s-%d”,名称,年龄);
}
公共静态void main(字符串参数[]){
最终列表人员=Arrays.asList(
新人(“约翰”,10岁),
新人(“格雷格”,30岁),
新人(“Sara”,20岁),
新人(“简”,15岁);
升序表=
people.stream()
.已排序(个人::年龄差异)
.collect(toList());
系统输出打印LN(上升页);
}
}
输出:[John-10,Jane-15,Sara-20,Greg-30]
我想你的主要困惑是:
Comparator
表示一种方法,它接受两个类型为T
的参数并返回一个int
。我的ageDifference
方法只接受一个Person
参数。这怎么会成为一个比较器呢
请注意,ageDifference
是一个实例方法。要调用它,不仅需要参数,还需要Person
的实例。在这种情况下,需要2个Person
s来调用方法-一个调用ageDifference
,另一个作为参数传递:
me.ageDifference(someoneElse)
^ ^
| |
Two people!
这不就是一个接受两个参数的静态方法吗
因此,Java非常聪明,知道需要两个人来调用Person::ageDifference
,因此方法引用被视为具有两个参数
通常,类T
的实例方法接受参数P1
,P2
Pn
和返回类型R
可以被视为一种静态方法,接受参数T
,P1
,P2
Pn
并返回R
我想您主要的困惑是:
Comparator
表示一种方法,它接受两个类型为T
的参数并返回一个int
。我的ageDifference
方法只接受一个Person
参数。这怎么会成为一个比较器呢
请注意,ageDifference
是一个实例方法。要调用它,不仅需要参数,还需要Person
的实例。在这种情况下,需要2个Person
s来调用方法-一个调用ageDifference
,另一个作为参数传递:
me.ageDifference(someoneElse)
^ ^
| |
Two people!
这不就是一个接受两个参数的静态方法吗
因此,Java非常聪明,知道需要两个人来调用Person::ageDifference
,因此方法引用被视为具有两个参数
通常,类T
的实例方法接受参数P1
,P2
Pn
和返回类型R
可以被视为一种静态方法,接受参数T
,P1
,P2
Pn
并返回R
右侧,比较器
是SAM类型。单一的抽象方法。因此编译器“只知道”替换Comparator
类型,并让它调用您提供的方法,Person::ageDifference
。Leonard Kraemer提供的链接解释得更详细。作为lambda,它看起来像:(p1,p2)->p1。年龄差异(p2)
对,比较器
是SAM类型。单一的抽象方法。因此编译器“只知道”替换Comparator
类型,并让它调用您提供的方法,Person::ageDifference
。Leonard Kraemer提供的链接更详细地解释了这一点。作为lambda,它看起来像:(p1,p2)->p1.ageDifference(p2)
为了完成您的好答案,上面代码编译的原因在于新的lambda功能在Java 8中的工作方式。它依赖于一个非正式称为“单一抽象方法(SAM)”接口的概念。基本思想是,如果lambda或方法引用与接口中的SAM匹配,则具有一个抽象方法的任何接口都可以由任何lambda或方法引用自动实现。为了完成您的好答案,上面代码编译的原因在于Java 8中新lambda功能的工作方式。它依赖于一个非正式称为“单一抽象方法(SAM)”接口的概念。其基本思想是,如果lambda或方法引用与接口中的SAM匹配,则具有一个抽象方法的任何接口都可以由任何lambda或方法引用自动实现。