数组有工具类Arrays,集合也有一个工具类Collections,这里练习一下集合工具类的排序方法,顺便过一下sort排序方法,比较器。
sort方法
-
sort(List<T> list):
根据其元素的natural ordering对指定的列表进行排序。 sort(List<T> list, Comparator<? super T> c):根据指定的比较器引起的顺序对指定的列表进行排序。
第一个方法使用:
public class Dome01 {
public static void main(String[] args) {
ArrayList<Integer> arrayList = new ArrayList<Integer>();
//Collections集合工具的添加方法
Collections.addAll(arrayList, 21,31,23,12,54,-21,3,98,0);
arrayList.forEach((s) -> System.out.print(s+" "));//依次输出并没有排序 21 31 23 12 54 -21 3 98 0
//调用sort方法排序
Collections.sort(arrayList);
arrayList.forEach((s) -> System.out.print(s+" "));//从小到大排序输出 -21 0 3 12 21 23 31 54 98
}
}
上面是针对int 数据类型的数据排序,在针对其他类型的数据时,使用sort排序就不会生效,如下:
public static void main(String[] args) {
ArrayList<Character> arrayList = new ArrayList<Character>();
Collections.addAll(arrayList, 'w','s','o','q');
arrayList.forEach((s) -> System.out.print(s)); // 依次打印 wsoq 并没有进行abc 做这样排序
}
这个时候,就要使用第二种方式了比较器实现
public static void main(String[] args) {
ArrayList<Character> arrayList = new ArrayList<Character>();
Collections.addAll(arrayList, 'f','s','q','h','1');
Collections.sort(arrayList, new Comparator<Character>() {
@Override
public int compare(Character o1, Character o2) {
return o1 - o2;
}
});
arrayList.forEach(s -> System.out.print(s+" "));//根据ASCII排序 1 f h q s
}
o1 - o2是从小到大排序,反过来就少从大到小,上面使用匿名内部类使用的。
排序自定义类型:
public class ComparatorDome {
public static void main(String[] args) {
Student[] student = new Student[5]; // 实例化Student并定义为数组
// 赋值 0 1 2 3 4 5
student[0] = new Student("zhangsan", 16);
student[1] = new Student("lisi", 22);
student[2] = new Student("wangwu", 19);
student[3] = new Student("tom", 27);
student[4] = new Student("tom", 17);
int a[] = { 32, 31, 2, 334, -212, 99 };
Arrays.sort(a); // Arrays.sort Arrays工具类提供方法排列数组
System.out.println(Arrays.toString(a));
/* Arrays工具类可以拍类基本数据类型的数组 但是怎么排列上面的学生类数据呢 */
/* 比较器的使用 */
// 第一种使用手动排序方法Comparator接口
Arrays.sort(student, new ComparatorDome02());
System.out.println(Arrays.toString(student));
// 第二种使用自然排序方法 Comparable接口
Arrays.sort(student);
System.out.println(Arrays.toString(student));
}
}
/*
* 由于接口无法实例化对象,所以我们,创建一个类来实现它 然后来创建这个类的对象
*/
class ComparatorDome02 implements Comparator<Student> { // Comparator是用来手动排序的类 Comparable是默认自然比较器
// 重写compareTo方法
@Override
public int compare(Student o1, Student o2) {
if (o1.getAge() - o2.getAge() == 0) {
return o1.getName().charAt(0) - o2.getName().charAt(0);
} else {
return o1.getAge() - o2.getAge();
}
}
/*
* 总结比较器: 在对Student排序的时候,由于在Arrays
* 工具类中没有定义Student类型的排序规则,jvm编译时在想我该怎么编译这个玩意呢,当然jvm毕竟是 机器它不会去思考,所以jvm直接反馈一个错误给我们
* java.lang.ClassCastException,所以可以想到jvm排序这个Student需要一个规则,一个叫jvm怎么去排序这个数组的规则。通过解刨源码
* 我们可以发现,在排序基本类型数据时,源码都继承了一个接口 Comparable<Integer>再次跟进 发现定义规则的抽象方法compareTo
* 照葫芦画瓢,我们定义规则并将规则传达给Arrays工具类,使其按照我们定义的规则来排序数组
* Comparable,Comparator两个比较器达到的目的都是一样的,但是实现方法两种:一个是在该Student类中直接定义 ,一个是假借他人之手
* 来制定规则, 排序的依旧是Arrays工具类,我们做的是制定规则
*/
}
Comparable和Comparator两个接口的区别
Comparable:强行对实现它的每个类的对象进行整体排序。这种排序被称为类的自然排序,类的compareTo方法被称为它的自然比较方法。只能在类中实现compareTo()一次,不能经常修改类的代码实现自己想要的排序。实现此接口的对象列表(和数组)可以通过Collections.sort(和Arrays.sort)进行自动排序,对象可以用作有序映射中的键或有序集合中的元素,无需指定比较器。
Comparator:强行对某个对象进行整体排序。可以将Comparator 传递给sort方法(如Collections.sort或Arrays.sort),从而允许在排序顺序上实现精确控制。还可以使用Comparator来控制某些数据结构(如有序set或有序映射)的顺序,或者为那些没有自然顺序的对象collection提供排序。