强制转换lambda表达式的返回类型,并使用自定义比较器对列表进行排序

强制转换lambda表达式的返回类型,并使用自定义比较器对列表进行排序,lambda,casting,java-8,method-reference,Lambda,Casting,Java 8,Method Reference,我有一个,希望使用自定义比较器按的属性对列表进行排序 为了提供一个简单的示例,我将使用用户对象Person public class Person { private String firstname; private String lastname; public Person(String firstname, String lastname) { this.firstname = firstname; this.lastname =

我有一个,希望使用自定义比较器按的属性对列表进行排序

为了提供一个简单的示例,我将使用用户对象
Person

public class Person {
    private String firstname;
    private String lastname;

    public Person(String firstname, String lastname) {
        this.firstname = firstname;
        this.lastname = lastname;
    }

    public String getFirstname() {
        return firstname;
    }

    public String getLastname() {
        return lastname;
    }

}
和一个自定义比较器

public class PersonComparator implements Comparator<Person> {

    @Override
    public int compare(Person o1, Person o2) {
        // to keep the example simple I just compare the firstnames here
        return o1.getFirstname().compareTo(o2.getFirstname());
    }

}
但是这(当然)给了我一个编译器错误,因为
DefaultMutableTreeNode.getUserObject()
返回的是
对象而不是

如何转换lambda方法引用的retrun类型
DefaultMutableTreeNode::getUserObject

或者你还有其他选择吗

编辑:

我可以这样做,但有更简单的方法吗?(一行)

Function userObject=DefaultMutableTreeNode::getUserObject;
sort(Comparator.comparing(userObject.and(Person.class::cast),myComparator));
您的问题谈到了“lambda方法引用”,但这并不存在:有,有。方法引用是一种特殊功能,在这种功能中,您不用编写一个lambda表达式来调用另一个现有方法,而是使用
操作符直接按名称引用该方法

但在这种情况下,由于
getUserObject
返回的是
对象而不是
,因此您将无法在此处直接使用方法引用:您需要更多的代码,而不仅仅是引用
getUserObject
:需要强制转换

因此,请使用lambda表达式:

nodes.sort(Comparator.comparing(t -> (Person) t.getUserObject(), myComparator));
另一种方法是创建一个返回
个人
而不是
对象
的方法,并引用该方法:

private static Person getPerson(DefaultMutableTreeNode node) {
    return (Person) node.getUserObject();
}

// assuming "getPerson" in a class called MyClass
nodes.sort(Comparator.comparing(MyClass::getPerson, myComparator)); 

请注意,
PersonComparator
可以更简单地用

Comparator<Person> myComparator = Comparator.comparing(Person::getFirstname);
Comparator myComparator=Comparator.comparing(Person::getFirstname);
您的问题谈到了“lambda方法引用”,但这并不存在:有,有。方法引用是一种特殊功能,在这种功能中,您不用编写一个lambda表达式来调用另一个现有方法,而是使用
操作符直接按名称引用该方法

但在这种情况下,由于
getUserObject
返回的是
对象而不是
,因此您将无法在此处直接使用方法引用:您需要更多的代码,而不仅仅是引用
getUserObject
:需要强制转换

因此,请使用lambda表达式:

nodes.sort(Comparator.comparing(t -> (Person) t.getUserObject(), myComparator));
另一种方法是创建一个返回
个人
而不是
对象
的方法,并引用该方法:

private static Person getPerson(DefaultMutableTreeNode node) {
    return (Person) node.getUserObject();
}

// assuming "getPerson" in a class called MyClass
nodes.sort(Comparator.comparing(MyClass::getPerson, myComparator)); 

请注意,
PersonComparator
可以更简单地用

Comparator<Person> myComparator = Comparator.comparing(Person::getFirstname);
Comparator myComparator=Comparator.comparing(Person::getFirstname);

节点.sort(比较(t->((Person)t.getUserObject()).getFirstname())
节点。排序(比较(t->((Person)t.getUserObject()).getFirstname())
PersonComparator
只是一个例子。我的实际比较器和用户对象以及比较逻辑更复杂。当然,对于这个简单的例子,您可以直接组合它们:
nodes.sort(comparator.comparating(t->)((Person)t.getUserObject()).getFirstname())
@RenéLink:如果您的自定义比较器包含比
比较器更复杂的逻辑。比较(X::oneProperty)。然后比较(X::nextProperty)
等提供的功能,您应该重新考虑您的设计。也许,更复杂的逻辑实际上与属性类型相关,应该从
Person
比较器中分离出来,就像
comparator.comparating(Person::getFirstname,Collator.getInstance())
…PersonComparator
就是一个例子。我的实际比较器和用户对象以及比较逻辑更复杂。当然,对于这个简单的例子,您可以直接组合它们:
nodes.sort(comparator.comparating(t->)((Person)t.getUserObject()).getFirstname())
@RenéLink:如果您的自定义比较器包含比
比较器更复杂的逻辑。比较(X::oneProperty)。然后比较(X::nextProperty)
等提供的功能,您应该重新考虑您的设计。也许,更复杂的逻辑实际上与属性类型相关,应该从
Person
比较器中分离出来,就像
comparator.comparating(Person::getFirstname,Collator.getInstance())