1. 在日常的代码中,我们常常会用到排序,这时候就会用到ComparableComparator
  2. 先使用Comparable进行举例:

定义ComparableUser 并实现Comparable接口

public class ComparableUser implements Comparable<ComparableUser> {

private int id;
private int age;

public ComparatorUser(){}

public ComparableUser(int id, int age) {
this.id = id;
this.age = age;
}

public int getId() {
return id;
}

public void setId(int id) {
this.id = id;
}

public int getAge() {
return age;
}

public void setAge(int age) {
this.age = age;
}

@Override
public String toString() {
return "ComparableUser{" +
"id=" + id +
", age=" + age +
'}';
}

// 重写的是compareTo方法
@Override
public int compareTo(ComparableUser o) {
// 如果id相同,则按照age升序
if (this.id == o.id) {
return this.age - o.age;
}
// 否则按照id升序排列
return this.id - o.id;
}
}

进行测试:

public class ComparableTest {
public static void main(String[] args) {
ComparableUser[] user = new ComparableUser[] {
new ComparableUser(4, 18),
new ComparableUser(4, 15),
new ComparableUser(7, 12),
new ComparableUser(1, 13),
};
Arrays.sort(user);
for (int i = 0; i < user.length; i++) {
System.out.println(user[i].toString());
}
}
}

结果如图:

Comparable和Comparator的使用和细节_ide


个人理解,Comparable是一个比较器,只是用来比较两个对象的区别(目前学习到这部分,应该还有其他的)。但是Comparable和目标类的耦合度太高,当需要调整算法,就得对原来的代码进行修改,这一点不符合设计模式的开闭原则。因此出现了Comparator接口

  1. 先使用Comparator进行举例:

定义ComparatorUser 并实现Comparator接口

public class ComparatorUser implements Comparator<ComparatorUser> {

private int id;
private int age;

public ComparatorUser(){}

public ComparatorUser(int id, int age) {
this.id = id;
this.age = age;
}

public int getId() {
return id;
}

public void setId(int id) {
this.id = id;
}

public int getAge() {
return age;
}

public void setAge(int age) {
this.age = age;
}

@Override
public String toString() {
return "ComparableUser{" +
"id=" + id +
", age=" + age +
'}';
}

// 注意,重写了compare方法
@Override
public int compare(ComparatorUser o1, ComparatorUser o2) {
if (o1.id == o2.id) {
return o1.age - o2.age;
}
return o1.id - o2.id;
}
}

进行测试:

public class ComparatorTest {
public static void main(String[] args) {
ComparatorUser[] user = new ComparatorUser[] {
new ComparatorUser(4, 18),
new ComparatorUser(4, 15),
new ComparatorUser(7, 12),
new ComparatorUser(1, 13),
};
// 注意,有排序器的实现
Arrays.sort(user, new ComparatorUser());
for (int i = 0; i < user.length; i++) {
System.out.println(user[i].toString());
}
}
}

测试结果同上
注意:使用Comparator接口,重写的方法是compare方法。另外,在排序过程中,应该有对应的Comparator接口的实现,如:​​​Arrays.sort(user, new ComparatorUser());​​,否则报错找不到的调用规则

  1. 先使用Comparator进行改进:

为了减少代码的耦合,并方便修改,而不改变原来的代码,我们定义 ComparatorUser 类,并不再实现Comparator 方法

public class ComparatorUser {

private int id;
private int age;

public ComparatorUser(){}

public ComparatorUser(int id, int age) {
this.id = id;
this.age = age;
}

public int getId() {
return id;
}

public void setId(int id) {
this.id = id;
}

public int getAge() {
return age;
}

public void setAge(int age) {
this.age = age;
}

@Override
public String toString() {
return "ComparableUser{" +
"id=" + id +
", age=" + age +
'}';
}
}

进行测试代码需要通过内部类的方式进行排序,如果变动只需要便内部类,不用修改原函数

public class ComparatorTest {
public static void main(String[] args) {
ComparatorUser[] user = new ComparatorUser[] {
new ComparatorUser(4, 18),
new ComparatorUser(4, 15),
new ComparatorUser(7, 12),
new ComparatorUser(1, 13),
};
// 通过内部类的方式实现排序规则
Arrays.sort(user, new Comparator<ComparatorUser>() {
@Override
public int compare(ComparatorUser o1, ComparatorUser o2) {
if (o1.getId() == o2.getId()) {
return o1.getAge() - o2.getAge();
}
return o1.getId() - o2.getId();
}
});
for (int i = 0; i < user.length; i++) {
System.out.println(user[i].toString());
}
}
}

使用lambda表达式进行简化

Arrays.sort(user, (o1, o2) -> {
if (o1.getId() == o2.getId()) {
return o1.getAge() - o2.getAge();
}
return o1.getId() - o2.getId();
}
);
  1. 总结
    想要对象进行排序,推荐实现Comparable接口,并重写compareTo方法,通过Arrays.sort();传入排序对象即可
    想要对对象及其以外且有可能变动代码的排序,推荐使用Comparator接口,并通过内部类是形式重写compare方法即可