如何在Java8中使用自定义比较器接口对对象数组进行排序?
比较器的定制实现如何在Java8中使用自定义比较器接口对对象数组进行排序?,java,sorting,interface,java-8,comparator,Java,Sorting,Interface,Java 8,Comparator,比较器的定制实现 @FunctionalInterface public interface Comparator<T> { int compare(T t1, T t2); static <T> Comparator<T> comparing( Function<T, Comparable> f){ return (p1, p2) -> f.apply(p1).compareTo(f.apply(p2)); }
@FunctionalInterface
public interface Comparator<T> {
int compare(T t1, T t2);
static <T> Comparator<T> comparing(
Function<T, Comparable> f){
return (p1, p2) -> f.apply(p1).compareTo(f.apply(p2));
}
default Comparator<T> thenComparing(
Comparator<T> cmp){
return (p1, p2) ->
this.compare(p1, p2) == 0 ?
cmp.compare(p1, p2) : this.compare(p1, p2);
}
default Comparator<T> thenComparing(
Function<T, Comparable> f){
Comparator<T> cmp = comparing(f);
return thenComparing(cmp);
}
}
@functioninterface
公共接口比较器{
int比较(t1,t2);
静态比较器比较(
函数f){
返回(p1,p2)->f.apply(p1)。与(f.apply(p2))比较;
}
默认比较器(
比较器(cmp){
返回(p1,p2)->
这个。比较(p1,p2)==0?
比较(p1,p2):这个比较(p1,p2);
}
默认比较器(
函数f){
比较器cmp=比较(f);
返回值(cmp);
}
}
我创建了一个Person类,它有三个字段,即firstName、lastName和age,以及它们各自的getter和setter。使用custom Comparator类,我想对一组主要人员进行排序,如下所示:
Comparator<Person> cmp = Comparator
.comparing(Person::getLastName) // Extract Property and compare
.thenComparing(Person::getFirstName)
.thenComparing(Person::getAge);
Person arr[] = new Person[]{
new Person("Sean", "Gilmore", 22),
new Person("Aaron", "Reidy", 21),
new Person("Jane", "Kennedy", 53),
new Person("Mike", "English", 49)
};
Arrays.sort(arr, cmp);
比较器cmp=比较器
.comparing(Person::getLastName)//提取属性并进行比较
.Then比较(Person::getFirstName)
.然后比较(Person::getAge);
人员arr[]=新人员[]{
新人(“肖恩”,“吉尔莫”,22岁),
新人(“Aaron”,“Reidy”,21岁),
新人(“简”,“肯尼迪”,53岁),
新人(“迈克”,“英语”,49)
};
排序(arr,cmp);
然而
Arrays.sort(arr,cmp)
抛出编译错误不存在类型变量T的实例,因此Comparator符合ComparatorJava中类的完全限定名包括其包名
该方法需要一个java.util.Comparator
实现。您的自定义比较器
与isjava.util.Comparator
不同
数组
类中的排序
方法是一种静态
方法,因此不能扩展数组
并重写此方法。如果要使用,请使用java.util.Comparator
的实现。这是没有办法的。您可以很容易地将比较器调整到JDK,如下所示:
Arrays.sort(arr, cmp::compare);
我相信Guava推荐了一种类似的模式来调整它们的功能接口,然后再对它们进行Java 8改造。这意味着我必须实现排序才能使用我的自定义比较器?@HarpreetSingh或者您为自定义的比较器类编写一个外观。不管怎样,你为什么不使用正版的比较器呢?@Flown该外观仍然是一个java.util.Comparator。@这就是我的意思。你为什么要重新发明轮子?@shmoseicmp:compare
仍然会给你一个java.util.Comparator
。还有其他选择,但最终只能将java.util.Comparator
传递给所讨论的方法,因此答案仍然是:您不能这样做。@CKK我没有将该问题解释为试图完全避免JDK的Comparator
。我想OP只是在问他的自定义接口如何与内置的排序功能一起使用。@shmosei我脑子里也有同样的想法,但后来我从问题中读到了这一行,我摆脱了这个错误,我想知道如何使用cmp Comparator对Person数组进行排序,这让我确信OP显然需要一个解释为什么不能做,而不是如何做。(OP因为无法将比较器
传递给使用比较器
的方法而被抛弃)。这可以从OP对我的答案的评论中进一步推断,这意味着我必须实现sort才能使用自定义比较器?OP正在全面探索Java@我听到了,但我怀疑你对OP的话考虑得比他多:)@CKing这是我完全同意的一个说法。