java arraylist 对象排序_Java ArrayList中对象的排序 (Comparable VS Comparator)

博客介绍了Java中ArrayList自定义对象的排序方法。对于由自定义对象组成的ArrayList,不能直接用Collections.sort()排序,需实现Comparable或Comparator接口。使用Comparable可按单一属性排序,而Comparator可实现多属性排序,还介绍了多属性组合排序的方式。

开发板推荐:天空星STM32F407VET6开发板

超高性价比 STM32主控 | 超高主频 | 一板兼容百芯 | 比赛神器 | 沉金彩色丝印

我们通常使用Collections.sort()方法来对一个简单的数据列表排序。但是当ArrayList是由自定义对象组成的,就需要使用comparable或者comparator接口了。在使用这两者进行排序之前,先尝试不实现任何接口来进行排序。

考虑下面的例子——有一个Student类,具有三个属性:name, rollno, age

public classStudent {privateString name;private introllno;private intage;/*有参构造 ...*/

/*getter and setter ...*/}

然后需要一个Student组成的ArrayList:

import java.util.*;public classArrayListSorting {public static voidmain(String args[]){

ArrayList arraylist = new ArrayList();

arraylist.add(new Student(223, "Chaitanya", 26));

arraylist.add(new Student(245, "Rahul", 24));

arraylist.add(new Student(209, "Ajeet", 32));

Collections.sort(arraylist);for(Student str: arraylist){

System.out.println(str);

}

}

}

这里尝试去调用Collections.sort()方法,但是出错了:

Exception in thread “main” java.lang.Error: Unresolved compilation problem:

Bound mismatch: The generic method sort(List) of type Collections is not applicable for the arguments (ArrayList). The inferred type Student is not a valid substitute for the bounded parameter > at beginnersbook.com.Details.main(Details.java:11)

原因:对于排序的ArrayList,除非其中元素实现了Comparable或者Comparator接口,否则不能调用Collections.sort方法。

使用Comparable对ArrayList进行排序

我们想要根据age对Student进行排序——实现Comparable接口,重写compareTo方法。

packagebeginnersbook.com;public class Student implementsComparable {privateString name;private introllno;private intage;/*有参构造*/...//getter and setter methods

...

@Overridepublic intcompareTo(Student comparestu) {int compareAge=((Student)comparestu).getAge();/*正序排列*/

return this.age-compareAge;/*逆序排列*/

//return compareAge-this.age;

}

@OverridepublicString toString() {return "[ rollno=" + rollno + ", name=" + name + ", age=" + age + "]";

}

}

现在我们可以正常调用Collections.sort方法了。

既然Comparable完成了我们的工作,为什么还需要Comparator呢?

使用Comparable接口我们只能根据一个属性对ArrayList进行排序。为了让排序可以根据多个属性进行,需要使用Comparator。

使用Comparator对ArrayList进行排序(多个属性)

重写Comparator的compare方法:

importjava.util.Comparator;public classStudent {privateString name;private introllno;private intage;/*有参构造*/...//Getter and setter methods

.../* 根据name进行排序*/

public static Comparator NameComparator = new Comparator() {public intcompare(Student s1, Student s2) {

String name1=s1.getName().toUpperCase();

String name2=s2.getName().toUpperCase();// 正序排列

returnStudentName1.compareTo(StudentName2);//逆序排列//return StudentName2.compareTo(StudentName1);

}};/* 根据rollno进行排序*/

public static Comparator StuRollno = new Comparator() {public intcompare(Student s1, Student s2) {int rollno1 =s1.getRollno();int rollno2 =s2.getRollno();/* 正序排列*/

return rollno1-rollno2;/* 逆序排列*/

//returnrollno2-rollno1;

}};

@OverridepublicString toString() {return "[ rollno=" + rollno + ", name=" + name + ", age=" + age + "]";

}

}

这样,我们就既可以用name进行排序,也可以用age进行排序,只需要在有不同的排序需求时,使用不同的Comparator就可以了(e.g. Collections.sort(arraylist, Student.NameComparator))。

多属性组合排序

上面对Java的ArrayList自定义排序进行了基本介绍,下面是工作中遇到的一个需求:

对于一个漏洞,有两个排序依据,首先根据是否修复来排序,其次按照严重程度排序,类似于SQL中的ORDER BY field1, field2,若field1相同,则比较field2

a5dc2d7feeaed1bedd76b21ce3d9b458.png

可以看到,右边的一列是按照未修复,已修复的顺序排列的,而左边也是按照风险程度由高到低排列,但是分别对应了是否修复的顺序。这种排序可以认为也是多属性排序,但是与上边讲到的多属性不同,这种方式是多种属性结合的排序方式,

public static Comparator loopholesComparator = new Comparator() {

@Overridepublic intcompare(Loopholes l1, Loopholes l2) {

Integer riskLevel1=l1.getRiskLevel();

Integer riskLevel2=l2.getRiskLevel();

Integer fixed1=l1.getFixed();

Integer fixed2=l2.getFixed();int fixedComp =fixed1.compareTo(fixed2);if (fixedComp != 0) {returnfixedComp;

}else{returnriskLevel1.compareTo(riskLevel2);

}

}

};

首先用fixed1与fixed2进行比较,若两者不相等,则直接排序,若两者相等(即compartTo返回0),继续比较风险等级并返回风险等级的排序结果。

开发板推荐:天空星STM32F407VET6开发板

超高性价比 STM32主控 | 超高主频 | 一板兼容百芯 | 比赛神器 | 沉金彩色丝印

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值