在java中经常涉及到 对象数组的比较的情况,常见的有两种方法来处理:
继承comparable接口,并实现compareTo()方法
内部比较器,一个persion类如果想要使用 comparable接口进行排序,则需要在类里继承接口,并且重写compareTo。
定义一个单独的对象比较器,继承自Comparator接口,实现compare()方法
外部比较器,用于对那些没有实现Comparable接口或者对已经实现的Comparable中的排序规则不满意的情况进行排序.无需改变类的结构,自己定义一个比较器,更加灵活;
-
Comparable是排序接口;若一个类实现了Comparable接口,就意味着“该类支持排序”。
而Comparator是比较器;我们若需要控制某个类的次序,可以建立一个“该类的比较器”来进行排序。
-
这两个不是非用哪个不可,有时候是都可以用的。比如
-
我们想按照people的age排序。有一个people类继承comparable接口,并在类里重写了compareTo方法的话,那我们就可以用people.sort(null)排序。
-
people类里重写compareTo如下
-
我们也可以考虑使用 Comparator 接口,这可以在 main 方法或其他方法中实现。
-
people.sort((p1, p2) -> Integer.compare(p1.getAge(), p2.getAge()));
-
还可以简化为people.sort(Comparator.comparingInt(p -> p.age));
java比较器:comparable接口
Comparable 接口仅仅只包括一个函数,如下
package java.lang;
import java.util.*;
public interface Comparable {
//必须实现的抽象方法
public int compareTo(T o);
}
注意:().compareTo()括号只能接受包装类型(Integer,string),不支持int。
比如对people的age排序(int类型的)
想用int的话使用Integer.compare(A,B)来代替(A).compareTo(B)作为返回值。
Integer.compare(A,B)可替换为
Collections.sort(people, Comparator.comparingInt(Person::getAge));
等价Collections.sort(people, Comparator.comparingInt(o->o.getAge()));
根据这个方法的返回值来判断
大于0:说明前一个比后一个大
小于0:说明前一个小于后一个
等于0:说明这两个一样大
举例:
比如x,y。x=“33”,y="34",x+y="3334",y+x="3433",所以return一个大于0的数,x和y互换位置
Arrays.sort(strs, (x, y) -> {
return (y + x).compareTo(x + y);
}
Comparator 比较器接口
我们若需要控制某个类的次序,而该类本身不支持排序(即没有实现Comparable接口);那么,我们可以建立一个“该类的比较器”来进行排序。这个“比较器”只需要实现Comparator接口即可。也就是说,我们可以通过“实现Comparator类来新建一个比较器”,然后通过该比较器对类进行排序。
Comparator.comparingInt和Comparator.comparing区别
comparing 通常用于 Comparable 类型的属性,而 comparingInt 专门用于 int 类型的属性。
comparing 接受 Function 类型的参数,而 comparingInt 接受 ToIntFunction 类型的参数。
当属性类型为 int 时,使用 comparingInt 可以避免装箱和拆箱操作,从而提高性能。
举例: Collections.sort(people, Comparator.comparing(Person::getName));
people.sort(Comparator.comparingInt(Person::getAge));
二维数组的比较:
对int类型的二维fans数组,按照每个数组的第一个位置的数升序。
Arrays.sort(fans, Comparator.comparingInt(arr -> arr[0]));
对int类型的二维fans数组,按照每个数组的第一个位置的数升序,如果第一个位置数相同,再按照第二个位置的元素升序。
Arrays.sort(fans,Comparator.<int[]>comparingInt(o->o[0])
.thenComparingInt(o->o[1]));
只按照一个的话,不用规定比较器将用于int[]类型的数组。否则要加<int[]>。
用list.sort排序list里面是int[]数组的话就是
用list排序list,就不用标明是<int[]>了。
listData.add(Arrays.asList(3, 2, 1));
listData.add(Arrays.asList(6, 5, 4));
listData.add(Arrays.asList(9, 8, 7));
listData.add(Arrays.asList(3, 1, 2));
// 定义Comparator并立即对List进行排序
Collections.sort(listData, Comparator.comparingInt(row -> row.get(0)) // 按第一列排序
.thenComparingInt(row -> row.get(1))); // 如果第一列相等,按第二列排序