转换lambda表达式的返回类型,并使用自定义比较器

时间:2016-10-06 08:57:48

标签: lambda casting java-8 method-reference

我有List<DefaultMutableTreeNode>并希望使用自定义比较器按userObject的属性对列表进行排序。

为了提供一个简单的例子,我将使用用户对象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());
    }

}

我的第一个想法是使用Comparator.comparing方法引用作为关键提取器和关键比较器。

public static void main(String[] args) {
    List<DefaultMutableTreeNode> nodes = new ArrayList<DefaultMutableTreeNode>();

    nodes.add(new DefaultMutableTreeNode(new Person("James", "Smith")));
    nodes.add(new DefaultMutableTreeNode(new Person("Paul", "Clark")));
    nodes.add(new DefaultMutableTreeNode(new Person("Anthony", "Brown")));

    Comparator<Person> myComparator = new PersonComparator();
    nodes.sort(Comparator.comparing(DefaultMutableTreeNode::getUserObject, myComparator));

}

但这给了我(当然)编译器错误,因为DefaultMutableTreeNode.getUserObject()返回Object而不是Person

如何构建lambda方法引用DefaultMutableTreeNode::getUserObject的后向类型?

或者您还有其他选择吗?

修改

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

Function<DefaultMutableTreeNode, Object> userObject = DefaultMutableTreeNode::getUserObject;
nodes.sort(Comparator.comparing(userObject.andThen(Person.class::cast), myComparator));

1 个答案:

答案 0 :(得分:4)

您的问题谈及&#34; lambda方法参考&#34;但这并不存在:有lambda expressions,有method-references。方法引用是一个特殊功能,在这里,您可以使用::运算符直接按名称引用该方法,而不是编写简单地调用另一个现有方法的lambda表达式。

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

因此,请使用lambda表达式:

nodes.sort(Comparator.comparing(t -> (Person) t.getUserObject(), myComparator));

另一种方法是创建一个返回Person而不是Object的方法,并参考该方法:

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);