总结:
要对元素进行比较排序的操作,那么元素得具有比较性。
基本数据类型本身就具备比较性,直接进行比较。
而非基本数据类型的对象没有比较性,那么就让对象实现comparable接口,使元素具备比较性。
比较排序的情景都可以用这个思路。
比如比较ip(127.0.0.1)将IP封装成对象,有4个int字段。
下面以比较Student(name、age、score)为例
需求:声明类Student,包含3个成员变量:name、age、score,创建5个对象装入TreeSet,按照成绩排序输出结果(考虑成绩相同的问题)
TreeSet集合特点参见:Java类成分图、面向对象简述
用到的知识:
1、TreeSet特点
2、如何让对象具备比较性
3、比较器的反转
思路:
* 新建一个学生类,实现comparable,让对象具备比较性
* 存进treeset集合,会被按元素的比较性进行排序
先来一下学生类
/**
* function : 学生类
* 具有name、age、score属性
* 实现Comparable接口,具备了比较性
*/
class Stu implements Comparable<Stu>
{
private String name;
private int age;
private int score;
public Stu(String name, int age, int score) {
super();
this.name = name;
this.age = age;
this.score = score;
}
/**
* 具体的比较方法:先比分数、再比年龄、然后比姓名
*/
public int compareTo(Stu stu) {
//如果分数相同,就比较年龄
if(this.score == stu.score)
{
//如果年龄也相同,那么就比较姓名
if(this.age == stu.age)
//如果姓名不同,按姓名排序;如果姓名也相同,那么就认为是同一个人
return this.name.compareTo(stu.name);
//年龄不同,就按年龄排序
return this.age - stu.age;
}
//成绩不同,按成绩进行排序
return this.score - stu.score;
}
//将学生对象信息以String形式返回
public String toString() {
return name+":"+age+":"+score;
}
}
public class StuComp {
public static void main(String[] args) {
//新建集合、存入元素
TreeSet<Stu> ts = new TreeSet<Stu>();
ts.add(new Stu("a2",23 ,80 ));
ts.add(new Stu("a1",26 ,83 ));
ts.add(new Stu("a3",22 ,94 ));
ts.add(new Stu("a4",28 ,89 ));
ts.add(new Stu("a5",21 ,80 ));
//之所以可以直接打印元素,因为Stu对象实现了toString方法
System.out.println(ts);
}
}
运行结果:
[a5:21:80, a2:23:80, a1:26:83, a4:28:89, a3:22:94]
我们发现,结果是按分数从低到高排的,怎么能让成绩从到低排序呢?
我们要去修改对象比较方法compareTo(Stu stu)的代码吗?
其实可以给TreeSet传一个比较器,就可以实现集合元素的反转。
将TreeSet<Stu> ts = new TreeSet<Stu>();修改为:
TreeSet<Stu> ts = new TreeSet<Stu>(Collections.reverseOrder());
即传入一个比较器Collections.reverseOrder()。
下面是文档说明:
TreeSet(Comparator<? super E> comparator)
构造一个新的空 TreeSet,它根据指定比较器进行排序。
集合工具类Collections的方法
static <T> Comparator<T> reverseOrder()
返回一个比较器,它强行逆转实现了 Comparable 接口的对象 collection 的自然顺序。