Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/374.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何从方法引用创建比较器?_Java_Lambda - Fatal编程技术网

Java 如何从方法引用创建比较器?

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

我正在学习lambda表达式。我不明白比较器是如何从方法引用返回的

我想按年龄对一份名单进行排序

要做到这一点,我有一种方法来找出年龄差异:

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或方法引用自动实现。