您的位置:首页 > 其它

对对象数组与存放对象数据的集合进行排序 —— Comparable接口的用法

2016-06-03 00:00 411 查看
摘要: Arrays 类和 Collections 类的 sort 方法可以分别对数组与集合进行排序,排序不仅仅局限于整型数据,甚至是对象数据也可以,具体怎么做呢?相信本文会为您带来答案!

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);

}

}


感谢阅读!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息