对对象数组与存放对象数据的集合进行排序 —— Comparable接口的用法
2016-06-03 00:00
411 查看
摘要: Arrays 类和 Collections 类的 sort 方法可以分别对数组与集合进行排序,排序不仅仅局限于整型数据,甚至是对象数据也可以,具体怎么做呢?相信本文会为您带来答案!
Arrays类的sort方法可以对整型数组进行升序排列:
控制台则输出:[1, 2, 3, 4, 5]
Collections类的sort方法可以对整型数据集合实现相同的功能:
输出为:[1, 2, 3, 4, 5]
其实,sort方法不仅仅可以对整型数据进行排序,也可以对对象数组与存放对象数据的集合进行排序,而且可以指定排序方式(升序或降序),但要求满足以下前提:对象所属的类必须实现了Comparable接口。
下面是Comparable接口的源代码:
在实现接口时,泛型<T>中的T需声明为欲排序对象的类型。
若一个数组或集合中存放的对象所对应的类实现了Comparable接口并重写了compareTo方法,那么在调用Arrays.sort或Collections.sort的时候就能够对数组或集合进行排序。具体实现的方式我们在这里不去讨论,因为那是Arrays类和Collections类中的内容(这两个类分别为对数组和集合进行相关操作的工具类,比如排序功能的实现),在这里我们着重探讨一下Comparable接口中的comparaTo抽象方法。
在调用s.compareTo(o)的时候,compareTo方法会比较两个对象的内容,并返回比较的结果。当s小于o时,返回一个负数;当s大于o时,返回一个正数;否则(s等于o)时,返回0。
因此,在实现类重写compareTo方法时,需要比较当前类中的属性(比如,年龄 age)与参数对象o对应属性(o.age)的大小,并根据需求(升序排列、降序排列)返回相应的值(正数或负数)。
这段话苦涩难懂,不过不用担心,接下来的例子会让你很轻松的理解它想表达的意思。
现有一简单的学生类 Student,类中包含学生的一些信息:姓名 name、年龄 age,包含构造方法对学生信息进行初始化,重写toString方法用来在控制台打印信息。代码如下:
创建一测试类,实例化5个学生,并存入Student类型的数组。代码如下:
现有需求:将数组中的学生按照年龄进行升序排列。
此时,便需要用到Arrays.sort方法。但前文已经说过,对对象数组进行排序需要对象所属类实现Comparable接口并重写compareTo方法。因此我们需要对Student类进行如下修改:
实现Comparable接口:
重写compareTo方法:
其实这个方法有改善的空间,Integer类有一个名为compare的静态方法,源代码如下:
方法体中的三元表达式的作用为:当 x < y 时,返回 -1;当 x > y 时,返回 1;否则返回 0。这正是我们所需要的。顺便一提,Double类也有这个方法,它能适用于double类型的数据,适用面更广。
修改后的compateTo方法:
怎么样,是不是简化了很多?若想按降序排列只要改变compare方法两个参数的位置就可以了(age 和 o.age)。
现在我们可以在Test类中调用sort方法,并用foreach循环将排序后的数组打印出来了:
打印结果为:
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:
Test:
感谢阅读!
Arrays类的sort方法可以对整型数组进行升序排列:
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]
其实,sort方法不仅仅可以对整型数据进行排序,也可以对对象数组与存放对象数据的集合进行排序,而且可以指定排序方式(升序或降序),但要求满足以下前提:对象所属的类必须实现了Comparable接口。
下面是Comparable接口的源代码:
public interface Comparable<T> { public int compareTo(T o); }
在实现接口时,泛型<T>中的T需声明为欲排序对象的类型。
若一个数组或集合中存放的对象所对应的类实现了Comparable接口并重写了compareTo方法,那么在调用Arrays.sort或Collections.sort的时候就能够对数组或集合进行排序。具体实现的方式我们在这里不去讨论,因为那是Arrays类和Collections类中的内容(这两个类分别为对数组和集合进行相关操作的工具类,比如排序功能的实现),在这里我们着重探讨一下Comparable接口中的comparaTo抽象方法。
在调用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); } }
感谢阅读!
相关文章推荐
- 在命令行用 sort 进行排序
- 文件遍历排序函数
- 关于C#中排序函数的总结
- C#选择排序法实例分析
- C#插入法排序算法实例分析
- C#实现Datatable排序的方法
- MYSQL必知必会读书笔记第五章之排序检索数据
- SQLSERVER的排序问题结果不是想要的
- Windows Powershell排序和分组管道结果
- C#通过IComparable实现ListT.sort()排序
- C#选择法排序实例分析
- SQL学习笔记四 聚合函数、排序方法
- C#对list列表进行随机排序的方法
- jQuery拖动元素并对元素进行重新排序
- 将MySQL查询结果按值排序的简要教程
- 经典排序算法之冒泡排序(Bubble sort)代码
- 一根网线内的8根线哪4根是传输数据的,哪四根是防干扰的
- 在ASP.NET 2.0中操作数据之二十四:分页和排序报表数据
- C语言实现选择排序、冒泡排序和快速排序的代码示例
- C#折半插入排序算法实现方法