Java 排序

来源:互联网 发布:linux下svn测试 编辑:程序博客网 时间:2024/06/05 08:54

1、Comparator和Comparable

Comparable 和 Comparator 都是用来实现集合中元素的比较、排序的。

只是 Comparable 是在集合内部定义的方法实现的排序,而Comparator 是在集合外部实现的排序,所以,如想实现排序,就需要在集合外定义 Comparator 接口的方法或在集合内实现 Comparable 接口的方法。

Comparator位于包java.util下,而Comparable位于包 java.lang下。

Comparable 是一个对象,本身就已经支持自比较所需要实现的接口(如 String、Integer 自己就可以完成比较大小操作,已经实现了Comparable接口)自定义的类要在加入list容器中后能够排序,可以实现Comparable接口,在用Collections类的sort方法排序时,如果不指定Comparator,那么就以自然顺序排序,这里的自然顺序就是实现Comparable接口设定的排序方式。

Comparator 是一个专用的比较器,当这个对象不支持自比较或者自比较函数不能满足你的要求时,你可以写一个比较器来完成两个对象之间大小的比较。

可以说一个是自已完成比较,一个是外部程序实现比较的差别而已。

用 Comparator 是策略模式(strategy design pattern),就是不改变对象自身,而用一个策略对象(strategy object)来改变它的行为。

2、Comparable接口强行对实现它的每个类的对象进行整体排序,此排序被称为该类的自然排序,Comparable类的compareTo()方法被称为它的自然比较法。实现Comparable接口的对象列表(或数组)可以通过Collections.sort()(或Arrays.sort())进行自动排序。

compareTo(Object o)方法用于比较当前对象与指定对象的顺序,如果该对象小于、等于或大于指定对象,则分别返回负整数、零或正整数。

public int compareTo(Object obj){//返回0,表示this==obj//返回正数,表示this>obj//返回负数,表示this<obj}

示例代码如下:

import java.util.Iterator;import java.util.Set;import java.util.TreeSet;public class SlefStudent implements Comparable<Object> {private String name;private Integer age;public SlefStudent (String name, int age){this.name = name;this.age = age;}@Override//重写compareTo()方法,实现Comparable接口public int compareTo(Object o) {SlefStudent s = (SlefStudent) o;if(s.getAge().compareTo(this.getAge()) > 0){return -1;} else if(s.getAge().compareTo(this.getAge()) == 0){return 0;} else{return 1;}}public Integer getAge() {return age;}public void setAge(Integer age) {this.age = age;}/** * 打印出Student类的相关信息,所以要重写toString()方法 */public String toString(){return "age: "+age+"  name: "+name;}public int hashCode(){return age*name.hashCode();}public boolean equals(Object o){SlefStudent s = (SlefStudent) o;return age == s.age&&name.equals(s.name);}public static void main(String[] args){Set<SlefStudent> ts = new TreeSet<SlefStudent>();SlefStudent s1 = new SlefStudent("jack", 18);SlefStudent s2 = new SlefStudent("lily", 17);SlefStudent s3 = new SlefStudent("john", 19);SlefStudent s4 = new SlefStudent("mike", 20);ts.add(s1);ts.add(s2);ts.add(s3);ts.add(s4);Iterator<SlefStudent> iter = ts.iterator();while(iter.hasNext()){System.out.println(iter.next());}}}


实现排序方法二:

Collections.sort(words, new Comparator<Object>() {public int compare(Object o1, Object o2) {Word w1 = (Word) o1;Word w2 = (Word) o2;if ((w2.getFreq() - w1.getFreq()) > 0) {return 1;} else {return -1;}}});

3、多种排序方式(自定义比较器)

前面实现Comparable接口可以完成TreeSet的排序要求,但使用Comparable接口定义排序顺序有一定的局限性,实现此接口的类只能按照compareTo()定义的这一种排序方式排序。如果同一类对象要有多种排序方式,则应该为其定义不同的比较器。比如要求为Student类添加一个分数属性,并且要提供分数对Student进行排序,以及提供年龄对Student排序,此时就需要定义多个不同的比较器了。

定义比较器实际上就是让自编写的类实现Comparator接口,重写Comparator接口中的比较方法compare(Object a, Object b)。

public int compare(Object o1, Object o2){//返回0,表示o1==o2//返回正数,表示o1>o2//返回负数,表示o1<o2}

示例代码如下:

定义Student类

public class Student {private String name;private int age;private int score;public Student (String name, int age, int score){this.name = name;this.age = age;this.score = score;}public String getName(){return name;}public void setName(String name){this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public int getScore() {return score;}public void setScore(int score) {this.score = score;}/** * 打印出Student类的相关信息,所以要重写toString()方法 */public String toString(){return "age: "+age+"  name: "+name+"  score: "+score;}public int hashCode(){return age*name.hashCode();}public boolean equals(Object o){Student s = (Student) o;return age == s.age&&name.equals(s.name);}}

创建SelfComparatorTreeSetTest类,演示自定义比较器的相关用法

import java.util.Comparator;import java.util.Iterator;import java.util.Set;import java.util.TreeSet;//学生年龄比较器class StudentAgeComparator implements Comparator<Student>{public int compare(Student o1, Student o2) {int i = o2.getAge() - o1.getAge();return i;}}//学生成绩比较器class StudentScoreComparator implements Comparator<Student>{public int compare(Student o1, Student o2){int i = o2.getScore() - o1.getScore();return i;}}public class SelfComparatorTreeSetTest {public static void main(String[] args){//创建TreeSet对象时选择比较器//Set<Student> set = new TreeSet<Student>(new StudentAgeComparator());Set<Student> set = new TreeSet<Student>(new StudentScoreComparator());Student s1 = new Student("jack", 18, 86);Student s2 = new Student("lily", 17, 90);Student s3 = new Student("john", 19, 80);Student s4 = new Student("mike", 20, 93);set.add(s1);set.add(s2);set.add(s3);set.add(s4);Iterator<Student> iter = set.iterator();while(iter.hasNext()){System.out.println(iter.next());}}}