方式一:不常用
让实体类实现Comparable接口,泛型是需要比较的类型,同时重写compareTo方法
缺点:对代码有侵入性。
public class Student implements Comparable<Student> {private String name;private double score;// 构造函数和其他方法省略@Overridepublic int compareTo(Student other) {return Double.compare(this.score, other.score); // 比较成绩}
}
重点:方式二:重写Comparator接口
注意,这里compare方法,返回值是int,所以如果是比较非int类型的数据,记得先转换成int。
String[] strings = {"123", "456"};Arrays.sort(strings,new Comparator<String>(){@Overridepublic int compare(String o1, String o2) {return Integer.parseInt(o1)-Integer.parseInt(o2);}});
对于compare方法:详见下面的二分搜索源码
pivot是当前需要被插入进去的数,a[mid]是原数组中的中间值,这个过程通过二分(数组是有序的)快速找到被插入进去的点,如果被插进去的值(新值)比中间值(旧值)小,则移动右指针(right = mid ,说明插入点在中间值的左边,因为mid = (left+right)/2 ),反之,在右边,移动左指针(left = mid+1)
当然,这里逻辑是基于比较器的,如果重写了,(默认升序,重写为降序),就完全相反了。
比如上面图:默认是o1 - o2 ,即新值如果小于旧值,移动右指针,插在左边。升序。
如果重写,即o2 - o1,即新值如果小于旧值,移动左指针,插在右边。降序。
if(c.compare(pivot,a[mid]) < 0) 其中 c是比较器,pivot是将要被插入的元素(新值),a[ mid ]是数组中,正在被二分查找比较的元素,我们重写比较器,其实也就是人为的改变走向,让本该去if分支的去了else,else的去到了if分支,进而改变左指针or 右指针的移动,进而改变了相对插入点的位置,左边or 右边,进而达到了升序or 降序。
默认升序!!! o1 - o2,如果需要改完降序,则反过来即可。
对于一个二维数组:其实就是很多个一维数组放一起
我们取每个二维数组的第一维(行),比较第一个元素,即10,2,1,6。
int[][] points = {{10, 16}, {2, 8}, {1, 6}, {6, 12}};// 对二维数组按照每行数组的第一个元素进行排序Arrays.sort(points, new Comparator<int[]>() {@Overridepublic int compare(int[] o1, int[] o2) {// 按照从小到大排序return o1[0] - o2[0];}});
如果说,第一个元素,相等,我们也可以比较第二个元素....
Arrays.sort(points, new Comparator<int[]>() {@Overridepublic int compare(int[] o1, int[] o2) {// 按照从小到大排序if(o1[0]!=o2[0]) {return o1[0] - o2[0];}else{return o1[1] -o2[1];}}});