Collections.sort()是java.util.Collections类中的静态方法,提供对集合内元素的排序功能(默认升序),与java.util.Arrays.sort()功能相类似。
sort()有两个overload方法:
public static <T extends Comparable<? super T>> void sort(List<T> list) {
list.sort(null);
}
public static <T> void sort(List<T> list, Comparator<? super T> c) {
list.sort(c);
}
来看一下一般使用sort()的简单用法示例:
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
public class CollectionsSort {
private static final Logger logger = LoggerFactory.getLogger(CollectionsSort.class);
public static void main(String[] args) {
List<Integer> list = new LinkedList<Integer>();
list.add(5);
list.add(1);
list.add(3);
logger.error("排序前:" + list.toString());
Collections.sort(list);
logger.info("排序后:" + list.toString());
}
}
瞅一下
java.lang.Integer的定义:public final class Integer extends Number implements Comparable<Integer>{
public int compareTo(Integer anotherInteger) {
return compare(this.value, anotherInteger.value);
}
}
原来它实现了
Comparable接口并override了compareTo()方法,故可调用上文中的第一个overload方法。另外,java.lang.String类同样实现了Comparable接口实现了compareTo()方法,提供按字符顺序(及字符串长度)的排序功能。public final class String
implements java.io.Serializable, Comparable<String>, CharSequence {}
而在实际应用中,对集合中对象的排序要比Integer复杂的多。
如何实现对复杂对象的排序呢?接下来我们尝试利用
通过Integer的定义我们不难想到可以使用与其相似的定义方法:实现接口
java.lang.Integer与java.lang.String的排序特性来实现自定义对象的排序。
通过Integer的定义我们不难想到可以使用与其相似的定义方法:实现接口
Comparable<T>public class Person implements Comparable<Person>{
private Integer age;
private String name;
public Person(Integer age,String name){
this.age = age;
this.name = name;
}
public Integer getAge() {
return age;
}
public String getName() {
return name;
}
public int compareTo(Person o) {
int ageResult = this.age.compareTo(o.getAge());//先按年龄
if(ageResult == 0){
return this.name.compareTo(o.getName());//后按名称字母顺序
}
return ageResult;
}
public String toString(){
return "age:" + this.age + " name:" + this.name;
}
}public class CollectionsSort {
private static final Logger logger = LoggerFactory.getLogger(CollectionsSort.class);
public static void main(String[] args) {
List<Person> list = new LinkedList<Person>();
Person first = new Person(12,"Jack");
Person second = new Person(8,"Julian");
Person third = new Person(12,"Andy");
Person fourth= new Person(12,"Adler");
list.add(first);
list.add(second);
list.add(third);
list.add(fourth);
logger.error("排序前:" + list.toString());
Collections.sort(list);
logger.info("排序后:" + list.toString());
}
}
通过实现
Comparable<T>接口并实现CompareTo()方法提供自定义排序规则,这样我们就实现了一个简单的对自定义对象进行自定义排序的小Demo,在这里先对他们按年龄升序排序,若年龄相等则按名字的字母顺序排序。 以上是模仿java.lang.Integer类的方式实现的对某对象集合的排序操作,那么如何利用第二个overload的方法实现同样的效果呢?从定义来看,我们只需要创建一个Comparator即可,并override其中的compare()方法,一般习惯使用内部类的方式。
public static void main(String[] args) {
List<Person> list = new LinkedList<Person>();
Person first = new Person(12,"Jack");
Person second = new Person(8,"Julian");
Person third = new Person(12,"Andy");
Person fourth = new Person(12,"Adler");
list.add(first);
list.add(second);
list.add(third);
list.add(fourth);
logger.info("排序前:" + list.toString());
Collections.sort(list);
logger.info("升序:" + list.toString());
Collections.sort(list, new Comparator<Person>() {
public int compare(Person o1, Person o2) {
int ageResult = o2.getAge().compareTo(o1.getAge());//年龄降序
if(ageResult == 0){
return o2.getName().compareTo(o1.getName());//名称降序
}
return ageResult;
}
});
logger.info("降序:" + list.toString());
}
这样通过
Comparator中的自定义规则完成了对象的降序排列。 ok,通过以上两种方式,我们都可以实现对某对象的排序功能,那么,Comparable与Comparator二者有什么分别呢?可以发现,当继承Comparable后,需要实现方法compareTo(),此时我们在就已经定义了对象的自然顺序;而使用Comparator则不同,它创建的是“该类的比较器”,而我可以在不同地方多次定义不同的比较规则。
正如下面所示,完全可以利用Comparator随意定制不同排序规则:
public static void main(String[] args) {
List<Person> list = new LinkedList<Person>();
Person first = new Person(12,"Jack");
Person second = new Person(8,"Julian");
Person third = new Person(12,"Andy");
Person fourth = new Person(12,"Adler");
list.add(first);
list.add(second);
list.add(third);
list.add(fourth);
logger.info("排序前:" + list.toString());
Collections.sort(list, new Comparator<Person>() {
public int compare(Person o1, Person o2) {
int ageResult = o2.getAge().compareTo(o1.getAge());//年龄降序
if(ageResult == 0){
return o2.getName().compareTo(o1.getName());//名称降序
}
return ageResult;
}
});
logger.info("规则一:" + list.toString());
Collections.sort(list, new Comparator<Person>() {
public int compare(Person o1, Person o2) {
int ageResult = o1.getAge().compareTo(o2.getAge());//仅按年龄升序
return ageResult;
}
});
logger.info("规则二:" + list.toString());
}
总的来说,Comparable是一个排序接口,规则总是只有一个;Comparator用于定义用户定制顺序,是比较接口。任何类如果本身不支持排序(即没有实现Comparable接口),我们便可以建立一个“该类的比较器”来进行排序(当然,即便实现Comparable接口同样可以自定义规则)。



No comments:
Post a Comment