List 中元素的排序
List 中的元素不一定都是 String, Number 这种类型的,遇到自定义的对象,需要按对象的某一个维度去排序,该如何做?这里用两种方式实现,但暂时不深究原理。个人较为推崇第二种方法,代码耦合少。
法一 让被排序元素实现 Comparable 接口
简单地说,就是让需要排序的元素实现 Comparable 接口,元素加入到 List 后,直接调用 Collections.sort(Object) 方法即可。参考代码如下:
public class Person implements Comparable<Person> {
private String name;
private int age;
private String email;
public Person() {
}
public Person(String name, int age, String email) {
this.name = name;
this.age = age;
this.email = email;
}
//... 此处省略 getter 和 setter 方法,以节省篇幅。
@Override
public String toString() {
return this.name + ": " + age;
}
@Override
public int compareTo(Person o) {
return this.getAge() - o.getAge();
}
}
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class Client {
public static void main(String[] args) {
Person p1 = new Person("Zhang San", 30, "zhangsan@hotmail.com");
Person p2 = new Person("Li Si", 29, "lisi@gmail.com");
Person p3 = new Person("Wang Wu", 100, "wangwu@yahoo.com");
List<Person> list = new ArrayList<Person>();
list.add(p1);
list.add(p2);
list.add(p3);
for (Person p : list) {
System.out.println(p);
}
Collections.sort(list);
for (Person p : list) {
System.out.println(p);
}
}
}
法二 单独实现 Comparator 接口
简单地说,这种方法不需要改变被排序元素的类,需要一个 Comparator 的实例,然后调用 Collections.sort(Object, Comparator) 方法。实际使用时,如果比较规则很简单,使用内部匿名类即可。这种方法可达到「非侵入式」(non-intrusive)。
public class Person {
private String name;
private int age;
private String email;
public Person() {
}
public Person(String name, int age, String email) {
this.name = name;
this.age = age;
this.email = email;
}
//... 此处省略 getter 和 setter 方法,以节省篇幅。
@Override
public String toString() {
return this.name + ": " + age;
}
}
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class Client1 {
public static void main(String[] args) {
Person p1 = new Person("Zhang San", 30, "zhangsan@hotmail.com");
Person p2 = new Person("Li Si", 29, "lisi@gmail.com");
Person p3 = new Person("Wang Wu", 100, "wangwu@yahoo.com");
List<Person> list = new ArrayList<Person>();
list.add(p1);
list.add(p2);
list.add(p3);
for (Person p : list) {
System.out.println(p);
}
Collections.sort(list, new Comparator<Person>() {
@Override
public int compare(Person o1, Person o2) {
return o1.getAge() - o2.getAge();
}
});
for (Person p : list) {
System.out.println(p);
}
}
}
Collections.sort 方法的第二个参数是一个匿名的 Comparator 子类,这个写法,很有些 FP(函数式编程) 的味道,不过这里传入的是类。这个 Client 类还可以用 Java 8的新语法改写为:
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* 本例应用 Java 8 的 lambda 表达式以及 forEach 循环
*/
public class Client2 {
public static void main(String[] args) {
Person p1 = new Person("Zhang San", 30, "zhangsan@hotmail.com");
Person p2 = new Person("Li Si", 29, "lisi@gmail.com");
Person p3 = new Person("Wang Wu", 100, "wangwu@yahoo.com");
List<Person> list = new ArrayList<>();
list.add(p1);
list.add(p2);
list.add(p3);
list.forEach(System.out::println);
Collections.sort(list, (o1, o2) -> {
return o1.getAge() - o2.getAge(); // 以年龄排序
});
list.forEach(System.out::println);
}
}