java比较器Comparator与Comparable
一、List容器排序方法
<T> void java.util.Collections.sort(List<T> list)
<T> void java.util.Collections.sort(List<T> list, Comparator<? super T> c)
二、实现Comparator接口,按照自定义规则进行排序
1.定义一个用户类
public class User {
private String name;
private int age;
public User(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "\n User [name=" + name + ", age=" + age + "]";
}
}
2.实现Comparator接口,按照age升序排列
import java.util.Comparator;
public class ComparatorByAge implements Comparator<User> {
@Override
public int compare(User o1, User o2) {
int o1age = o1.getAge();
int o2age = o2.getAge();
if (o1age < o2age) {
return -1;
} else if (o1age == o2age) {
return 0;
} else {
return 1;
}
}
}
3.排序
public static void main(String args[]) {
List<User> users = new ArrayList<>();
users.add(new User("father", 36));
users.add(new User("mother", 36));
users.add(new User("grandmother", 50));
users.add(new User("me", 12));
System.out.println("before sorted:" + users);
Collections.sort(users, new ComparatorByAge());
System.out.println("after sorted:" + users);
}
/* 输出结果
before sorted:[
User [name=father, age=36],
User [name=mother, age=36],
User [name=grandmother, age=50],
User [name=me, age=12]]
after sorted:[
User [name=me, age=12],
User [name=father, age=36],
User [name=mother, age=36],
User [name=grandmother, age=50]]
*/
二、需要排序的类直接实现Comparable接口。定义一个且仅一个排序规则
1.定义一个学生类,基于分数升序排序
public class Student implements Comparable<Student> {
private String name;
private Integer score;
public Student(String name, Integer score) {
this.name = name;
this.score = score;
}
@Override
public int compareTo(Student o) {
return this.score.compareTo(o.score);
}
@Override
public String toString() {
return "\n Student [name=" + name + ", score=" + score + "]";
}
}
2.排序
public static void main(String args[]) {
List<Student> list = new ArrayList<>();
list.add(new Student("学霸", 100));
list.add(new Student("学渣", 60));
list.add(new Student("普通", 80));
Collections.sort(list);
System.out.println(list);
Set<Student> treeset = new TreeSet<>();
treeset.add(new Student("学霸", 100));
treeset.add(new Student("学渣", 60));
treeset.add(new Student("普通", 80));
System.out.println(treeset);
}
/* [
Student [name=学渣, score=60],
Student [name=普通, score=80],
Student [name=学霸, score=100]]
[
Student [name=学渣, score=60],
Student [name=普通, score=80],
Student [name=学霸, score=100]]
*/
总结:对象T排序规则有时会有多个,可以定义多个实现了Comparator<T>
接口的比较器,调用Collections.sort(List<T> list, Comparator<? super T> c)
,指定比较器进行排序。
当对象T一般只有一个排序规则时,或者一般是自然排序规则的时候,对象直接实现Comparable接口,调用Collections.sort(List<T> list)
方法排序,对于TreeSet这样的有序集合会自动按照定义的规则排序。
相对来说Comparator就像一个很灵活的工具,需要什么样的排序规则立马定义一个。而Comparable更像是对这个类T的补充,明确之间的排序规则。当用到排序时就默然按照这样的规则执行。
一般某规则排序只需要用一次的话,可以通过一个实现了Comparator的匿名内部类达到排序的目的
public static void main(String args[]) {
List<User> users = new ArrayList<>();
users.add(new User("father", 36));
users.add(new User("mother", 36));
users.add(new User("grandmother", 50));
users.add(new User("me", 12));
System.out.println("before sorted:" + users);
Collections.sort(users, new Comparator<User>() {
@Override
public int compare(User o1, User o2) {
Integer a = o1.getAge();
Integer b = o2.getAge();
return a.compareTo(b);
}
});
System.out.println("after sorted:" + users);
}
// before sorted:[
// User [name=father, age=36],
// User [name=mother, age=36],
// User [name=grandmother, age=50],
// User [name=me, age=12]]
// after sorted:[
// User [name=me, age=12],
// User [name=father, age=36],
// User [name=mother, age=36],
// User [name=grandmother, age=50]]
上段代码中的a.compareTo(b) 返回-1、0、1,因为Integer实现了Comparable接口。
联想:
1.已知实现了Comparable的类
2.常见类实现Comparable接口
//Integer实现Comparable接口中的compareTo方法源码
public int compareTo(Integer anotherInteger) {
return compare(this.value, anotherInteger.value);
}
public static int compare(int x, int y) {
return (x < y) ? -1 : ((x == y) ? 0 : 1);
}
//String实现Comparable接口中的compareTo方法源码
public int compareTo(String anotherString) {
int len1 = value.length;
int len2 = anotherString.value.length;
int lim = Math.min(len1, len2);
char v1[] = value;
char v2[] = anotherString.value;
int k = 0;
while (k < lim) {
char c1 = v1[k];
char c2 = v2[k];
if (c1 != c2) {
return c1 - c2;
}
k++;
}
return len1 - len2;
}
官方解释:Comparable接口强行对实现它的每个类的对象进行整体排序。这种排序被称为类的自然排序,类的 compareTo 方法被称为它的自然比较方法。
也就是说java提供的已经实现了Comparable接口的类的排序一般都是自然排序。
这也就是为什么 Collections.sort(List<String> list)
、 Collections.sort(List<Integer> list)
可以对list进行排序,不用指定特定的比较器,因为String、Integer这些类已经实现了Comparable接口,并且定义了自然排序规则排序(字典序升序)
提高:
上一篇: Expected MultipartHttpServletRequest: is a MultipartResolver configured?
下一篇: 【链表】18题-删除链表中重复的节点
推荐阅读
-
java网下商城与php网下商城比较
-
整理的比较全的event对像在ie与firefox浏览器中的区别_javascript技巧
-
浅析Java中的GC垃圾回收器的意义及与GC的交互
-
Java笔记-CXF增加拦截器与自定义拦截器
-
PHP、Java、C#实现URI参数签名算法,确保应用与REST服务器之间的
-
《深入理解java虚拟机》学习笔记--第三章:垃圾收集器与内存分配策略 jvm
-
《深入理解java虚拟机》学习笔记--第三章:垃圾收集器与内存分配策略 jvm
-
Java8比较器-如何对List排序详解
-
Java 中Comparable和Comparator区别比较
-
java 与web服务器链接的实例