Arrays类的sort方法能够对整型数组进行升序排列:java
int[] i = { 1, 5, 2, 4, 3 }; Arrays.sort(i); System.out.println(Arrays.toString(i));
控制台则输出:[1, 2, 3, 4, 5]算法
Collections类的sort方法能够对整型数据集合实现相同的功能:数组
List<Integer> l = new ArrayList<>(); l.add(1); l.add(5); l.add(2); l.add(4); l.add(3); Collections.sort(l); System.out.println(l);
输出为:[1, 2, 3, 4, 5]ide
其实,sort方法不单单能够对整型数据进行排序,也能够对对象数组与存放对象数据的集合进行排序,并且能够指定排序方式(升序或降序),但要求知足如下前提:对象所属的类必须实现了Comparable接口。工具
下面是Comparable接口的源代码:测试
public interface Comparable<T> { public int compareTo(T o); }
在实现接口时,泛型<T>中的T需声明为欲排序对象的类型。this
若一个数组或集合中存放的对象所对应的类实现了Comparable接口并重写了compareTo方法,那么在调用Arrays.sort或Collections.sort的时候就可以对数组或集合进行排序。具体实现的方式咱们在这里不去讨论,由于那是Arrays类和Collections类中的内容(这两个类分别为对数组和集合进行相关操做的工具类,好比排序功能的实现),在这里咱们着重探讨一下Comparable接口中的comparaTo抽象方法。code
在调用s.compareTo(o)的时候,compareTo方法会比较两个对象的内容,并返回比较的结果。当s小于o时,返回一个负数;当s大于o时,返回一个正数;不然(s等于o)时,返回0。对象
所以,在实现类重写compareTo方法时,须要比较当前类中的属性(好比,年龄 age)与参数对象o对应属性(o.age)的大小,并根据需求(升序排列、降序排列)返回相应的值(正数或负数)。排序
这段话苦涩难懂,不过不用担忧,接下来的例子会让你很轻松的理解它想表达的意思。
现有一简单的学生类 Student,类中包含学生的一些信息:姓名 name、年龄 age,包含构造方法对学生信息进行初始化,重写toString方法用来在控制台打印信息。代码以下:
public class Student { private String name; private int age; public Student(String name, int age) { this.name = name; this.age = age; } @Override public String toString() { return "Student [name=" + name + ", age=" + age + "]"; } }
建立一测试类,实例化5个学生,并存入Student类型的数组。代码以下:
public class Test { public static void main(String[] args) { Student s1 = new Student("张三", 20); Student s2 = new Student("李四", 18); Student s3 = new Student("王五", 22); Student s4 = new Student("赵六", 19); Student s5 = new Student("孙七", 21); Student[] s = { s1, s2, s3, s4, s5 }; } }
现有需求:将数组中的学生按照年龄进行升序排列。
此时,便须要用到Arrays.sort方法。但前文已经说过,对对象数组进行排序须要对象所属类实现Comparable接口并重写compareTo方法。所以咱们须要对Student类进行以下修改:
实现Comparable接口:
public class Student implements Comparable<Student> { // 泛型T改成欲排序的对象所属的类(Student)
重写compareTo方法:
@Override public int compareTo(Student o) { if (age < o.age) { return -1; // 这里的-1能够改为任意负数,若想按降序排列则改成返回一个正数 } else if (age > o.age) { return 1; // 若想按降序排列则改成返回一个负数 } else { return 0; } }
其实这个方法有改善的空间,Integer类有一个名为compare的静态方法,源代码以下:
public static int compare(int x, int y) { return (x < y) ? -1 : ((x == y) ? 0 : 1); }
方法体中的三元表达式的做用为:当 x < y 时,返回 -1;当 x > y 时,返回 1;不然返回 0。这正是咱们所须要的。顺便一提,Double类也有这个方法,它能适用于double类型的数据,适用面更广。
修改后的compateTo方法:
@Override public int compareTo(Student o) { return Integer.compare(age, o.age); }
怎么样,是否是简化了不少?若想按降序排列只要改变compare方法两个参数的位置就能够了(age 和 o.age)。
如今咱们能够在Test类中调用sort方法,并用foreach循环将排序后的数组打印出来了:
Arrays.sort(s); for (Student ss : s) System.out.println(ss); // 这里可以直接输出Student的对象是由于Student类中重写了toString方法
打印结果为:
Student [name=李四, age=18]
Student [name=赵六, age=19]
Student [name=张三, age=20]
Student [name=孙七, age=21]
Student [name=王五, age=22]
至此,咱们已经实现了对对象数组的排序操做。
若想对存放对象数据的集合进行排序须要执行的操做是相似的,只要将对象存到集合就能够了。
不过这里须要注意的是,TreeSet集合自己便具备排序的功能,所以,若是一个TreeSet中存放的对象数据所对应的类没有实现Comparable接口,那么在对这个TreeSet进行操做的时候会抛出一个ClassCastException(类型转换异常),它会提示你存放的数据没法转换成Comparable类型。
在本文中,咱们进行排序操做时均选择了整型的数据,好比整型数组和整型数据集合,对对象数组的排序也选择了以整型的年龄做为判断的依据。其实,sort方法的排序依据不单单局限于整型,只要制定好排序的规则,即可以按照需求作出相应的排序操做,好比按照姓名的首字母进行排序等,这些更复杂的需求须要咱们对sort方法进行深刻的研究,也须要在重写compareTo方法时给出更复杂的算法。若是你有兴趣,能够去尝试一下,相信你必定会成功!
在本文的最后我会放上Student类和Test类的所有代码,供参考用。
若是您看到了这里,我表示由衷的感谢,这是个人第一篇博文,但愿您之后能多多支持!
Student:
public class Student implements Comparable<Student> { private String name; private int age; public Student(String name, int age) { this.name = name; this.age = age; } @Override public String toString() { return "Student [name=" + name + ", age=" + age + "]"; } @Override public int compareTo(Student o) { return Integer.compare(age, o.age); } }
Test:
import java.util.Arrays; public class Test { public static void main(String[] args) { Student s1 = new Student("张三", 20); Student s2 = new Student("李四", 18); Student s3 = new Student("王五", 22); Student s4 = new Student("赵六", 19); Student s5 = new Student("孙七", 21); Student[] s = { s1, s2, s3, s4, s5 }; Arrays.sort(s); for (Student ss : s) System.out.println(ss); } }
感谢阅读!