强制转换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())
…