数组有工具类Arrays,集合也有一个工具类Collections,这里练习一下集合工具类的排序方法,顺便过一下sort排序方法,比较器。
sort方法
根据其元素的natural ordering对指定的列表进行排序。sort(List
list): sort(List
list, Comparator super T> c):根据指定的比较器引起的顺序对指定的列表进行排序。
第一个方法使用:
public class Dome01 { public static void main(String[] args) { ArrayListarrayList = new ArrayList (); //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) { ArrayListarrayList = new ArrayList (); Collections.addAll(arrayList, 'w','s','o','q'); arrayList.forEach((s) -> System.out.print(s)); // 依次打印 wsoq 并没有进行abc 做这样排序 }
这个时候,就要使用第二种方式了比较器实现
public static void main(String[] args) { ArrayListarrayList = new ArrayList (); Collections.addAll(arrayList, 'f','s','q','h','1'); Collections.sort(arrayList, new Comparator () { @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{ // 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 再次跟进 发现定义规则的抽象方法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提供排序。