Java的Comparable与Comparator
Collections
讲Comparable
与Comparator
之前先讲一下Collections
,然后再引出Comparable
与Comparator
。
定义:
集合工具类,用来对集合进行操作。
部分方法如下:
public static boolean addAll(Collection c, T… elements) | 往集合中添加一些元素 |
---|---|
public static void shuffle(List<?> list) | 打乱集合顺序 |
public static void sort(List list) | 将集合中元素按照默认规则排序 |
public static void sort(List list,Comparator<? super T> ) | 将集合中元素按照指定规则排序 |
代码演示:
public class CollectionsDemo {
public static void main(String[] args) {
ArrayList<Integer> list = new ArrayList<Integer>();
//原来写法
//list.add(12);
//list.add(14);
//list.add(15);
//list.add(1000);
//采用工具类 完成 往集合中添加元素
Collections.addAll(list, 5, 222, 1,2);
System.out.println(list);
//排序方法
Collections.sort(list);
System.out.println(list);
}
}
结果:
[5, 222, 1, 2]
[1, 2, 5, 222]
集合按照顺序进行了排列,可是这样的顺序是采用默认的顺序,如果想要指定顺序那该怎么办呢?我们可以使用
Comparable
与Comparator
说到排序了,简单的说就是两个对象之间比较大小,那么在JAVA中提供了两种比较实现的方式,一种是
比较死板的采用
java.lang.Comparable
接口去实现,一种是灵活的当我需要做排序的时候在去选择的
java.util.Comparator
接口完成。
Comparable比较器
定义:
该接口对实现它的每个类的对象强加一个整体排序。 这个排序被称为类的自然排序 ,类的compareTo
方法被称为其自然比较方法 。
compareTo
可以重写,从而实现自定义排序。
Comparator比较器
定义:
比较功能,对一些对象的集合施加了一个整体排序 。
比较的方法就是:
public int compare(String o1, String o2)
:比较其两个参数的顺序。
两个对象比较的结果有三种:大于,等于,小于。
如果要按照升序排序,
则o1 小于o2,返回(负数),相等返回0,01大于02返回(正数)
如果要按照降序排序
则o1 小于o2,返回(正数),相等返回0,01大于02返回(负数)
简述Comparable和Comparator两个接口的区别。
Comparable:强行对实现它的每个类的对象进行整体排序。这种排序被称为类的自然排序,类的
compareTo
方法被称为它的自然比较方法。只能在类中实现compareTo()
一次,不能经常修改类的代码
实现自己想要的排序。实现此接口的对象列表(和数组)可以通过Collections.sort
(和Arrays.sort
)进
行自动排序,对象可以用作有序映射中的键或有序集合中的元素,无需指定比较器。
Comparator强行对某个对象进行整体排序。可以将Comparator
传递给sort
方法(如Collections.sort
或 Arrays.sort
),从而允许在排序顺序上实现精确控制。还可以使用Comparator
来控制某些数据结构(如有序set
或有序映射)的顺序,或者为那些没有自然顺序的对象collection
提供排序。
题例
用一个题例来说明
题目:分别用
Comparable
和Comparator
两个接口对下列四位同学的成绩做降序排序,如果成绩一样,那在 成绩排序的基础上按照年龄由小到大排序
代码演示:
package com.Leve.Leve4.Leve4_3;
import java.util.*;
//实现Comparable接口
class Student implements Comparable<Student> {
private String name;
private int age;
private double grades;
public Student(String name, int age, double grades) {
this.name = name;
this.age = age;
this.grades = grades;
}
public Student() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
", grades=" + grades +
'}';
}
public void setGrades(float grades) {
this.grades = grades;
}
public double getGrades() {
return grades;
}
public void setAge(int age) {
this.age = age;
}
public int getAge() {
return age;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Student student = (Student) o;
return age == student.age && Double.compare(student.grades, grades) == 0 && Objects.equals(name, student.name);
}
@Override
public int hashCode() {
return Objects.hash(name, age, grades);
}
/**
* 重写compareTo方法
* @param o
* @return
*/
@Override
public int compareTo(Student o) {
//降序
if (this.grades > o.grades)
return -1;
else if (this.grades == o.grades)
return 0;
return 1;
}
}
public class Demo4 {
public static void main(String[] args) {
TreeSet<Student> data = new TreeSet<>(new Comparator<Student>() {
/**
* 使用compare方法进行年龄排序
* 如果成绩相等,则按年龄从小到大排序
* @param o1
* @param o2
* @return
*/
@Override
public int compare(Student o1, Student o2) {
int n1 = (int) (o1.getGrades() - o2.getGrades());
int n2 = o1.getAge() - o2.getAge();
return n1 == 0 ? n2 : (n1 * (-1));
}
});
Student s1 = new Student("张三", 21, 92.5);
Student s2 = new Student("李四", 17, 85.6);
Student s3 = new Student("王五", 18, 92.5);
Student s4 = new Student("麻子", 15, 93.6);
data.add(s1);
data.add(s2);
data.add(s3);
data.add(s4);
for (Student s : data) {
System.out.println(s);
}
}
}
结果:
Student{
name='麻子', age=15, grades=93.6}
Student{
name='王五', age=18, grades=92.5}
Student{
name='张三', age=21, grades=92.5}
Student{
name='李四', age=17, grades=85.6}