案例:TreeSet集合可以自动对基本数据类型和引用数据类型的一个升序排序,但不能对自定义类类型进行排序。此时若想让其对自定义类类型数据进行升序或降序排序又该如何去解决?
方法一:
有如下代码进行分析:
//假设声明一个集合来存储自定义类User且将该自定义类按个人自定义规则进行排序输出
Set<User> U=new TreeSet();//创建一个存储User对象的一个集合
//向集合中进行添加对象,且每个对象的值不一
U.add(new User("cc",20));
U.add(new User("dd",20));
U.add(new User("aa",22));
U.add(new User("bb",19));
for(User i:U){
System.out.println(i);//进行遍历输出结果
}
//声明User类且去实现Compareble接口
class User implements Comparable<User>{
String name;
int age;
public User() {
}
public User(String name, int age) {
this.name = name;
this.age = age;
}
//创建类的良好习惯要重写里头的toString,且该toString的重写是必须的
public String toString(){
return "age="+age+"name="+name;
}
//自定义规则:此规则为按年龄从小到大排序,当年龄相同时则按姓名字母排序
public int compareTo(User u){
if(this.age==u.age){
return this.name.compareTo(u.name);
}
else{
return this.age-u.age;
}
}
}
由上图可看出若想让TreeSet集合按个人自定义规则进行排序输出,则自定义的类需要去实现Comparable接口且需要去重写compareTo方法,重写该方法的过程称为自定义规则,也就是会让集合遍历输出的结果按此规则进行排序输出。但值得注意的是,若仅仅只去进行compareTo方法的重写而忽略的toString方法的重写,则打印输出的类型值是一个int类型,所以接下来必须对该类的toString方法进行重写。
方法二:
有如下代码进行分析:
//假设有集合TreeSet,需要去向该集合中的自定义类进行排序输出
Set<Animal> S=new TreeSet(new AnimalComparator());//将比较器传入该集合的形参中
S.add(new Animal(22));
S.add(new Animal(19));
S.add(new Animal(21));
S.add(new Animal(18));
for(Animal i:S){
System.out.println(i);//进行遍历输出结果
}
//声明一个Animal类
class Animal{
int age;
public Animal(int age){
this.age=age;
}
public String toString(){
return "age="+age;
}
}
//声明一个比较器去让Animal按年龄来排序
class AnimalComparator implements Comparator<Animal> {
public int compare(Animal a, Animal a1) {
return a.age-a1.age;//进行升序排序输出
//若降序则两者顺序相反
}
}
该方法就是去声明一个比较器,后在比较器中去自定义规则而后在该比较器传入集合中即可。就是在new这个集合的时候给这个集合去传一个比较器,所以在下方可以写一个比较器去实Comparator然后在这个实现类中去重写一个compare方法,且该方法的形参是两个同类中的不同变量,然后进行自定义规则即可,值得注意的是comparator与comparable有所不同的是前者是在util包下的后者是在lang包下的,也就是说前者需要导包,当然传这个比较器的时候也可以传一个内部类的方式,在该内部类中去实现这个比较器的一个功能即可。匿名内部类去实现该排序的写法可由如下进行参考:
Set<Animal> S=new TreeSet(new Comparator<Animal>(){
@Override
public int compare(Animal a, Animal a1) {
return a.age-a1.age;
}
});//将比较器传入该集合的形参中
S.add(new Animal(22));
S.add(new Animal(19));
S.add(new Animal(21));
S.add(new Animal(18));
for(Animal i:S){
System.out.println(i);//进行遍历
}
}
当比较规则只有一个的时候或者是比较规则不会发生改变的时候我们可以去使用实现Comparable的方式去进行一个排序的选择当比较规则是有多个且切换比较平凡的时候我们就可使用Comparator的方式进行。但不管是方法一或是方法二我们都应去将自定义类中的toString方法进行重写,这也是创建类的一个良好习惯。
值得注意的是在个人已测试的集合中仅有TreeSet集合支持传输比较器的这种写法。其他集合若想让其让自定义类类型按升降序排序输出则可让其去实现Comparable这种写法即可。
以上均个人小白理解,如有误,各位大侠可指出。
感谢