Comparable与Comparator用法与面试题总结
1. 概述
Java中对集合对象或者数组对象排序,有两种方法
- 对象实现Comparable 接口
- 定义比较器,实现Comparator接口。
2. 案例:排序按年龄从小到大的人
通过案例:得出排序从小到大的人来说明Comparable与comparator的区别
Comparable
1.包括实体类与实现comparable重写ComparaTo方法
写一个实体类Person
package xml.work;
import java.util.Comparator;
public class Person implements Comparable<Person>{
private String name;
private int age;
private int money;
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;
}
public int getMoney() { r
eturn money;
}
public void setMoney(int money) {
this.money = money;
}
public Person(String name, int age, int money) {
super();
this.name = name;
this.age = age;
this.money = money;
}
@Overridepublic String toString() {
return "Person [name=" + name + ", age=" + age + ", money=" + money + "]";
}
/** * * 这里是通过“person的年龄”进行比较的 * 注意:在做自然排序方法重写的时候,一定先判断主要条件,再判断次要条件 * * * */
@Overridepublic int compareTo(Person o) {//重写的方法
System.out.println("this.age="+this.age+":o.age="+o.age+"="+(this.age-o.age)); return this.age-o.age;//升序
}
}
2.写一个测试类Test.
package xml.work;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.TreeSet;
/** * Comparable 中译:比较性 *实现 “Comparable<String>” 的接口,即重写compareTo<T t>函数。 * @author 2019071003 * */
public class Test1 {
public static void main(String[] args) { //comparable案例调用的方法 TreeSet<Person> set=new TreeSet<>(); //comparator -排序年龄从小到大 //TreeSet<Person> set=new TreeSet<>(new PersonAgeComp()); //comparator -排序拥有的金钱从多到少
//TreeSet<Person> set=new TreeSet<>(new PersonMoneyComp()); set.add(new Person("阿姨", 20, 1000));
set.add(new Person("小媚", 12, 2000));
set.add(new Person("张三", 50, 100000));
set.add(new Person("杨过", 18, 17999));
Iterator it=set.iterator(); while(it.hasNext()) {
System.out.println(it.next());
}
}}
若是降序把 this.age-o.age—改成—》return o.age-this.age;
升序效果
Comparator案例
package xml.work;
import java.util.Comparator;
/**Comparator
* * 比较年龄
* * @author 2019071003
* */
public class PersonAgeComp implements Comparator<Person>{
@Override
public int compare(Person p1, Person p2) {
int num=p1.getAge()-p2.getAge();//主要条件 若p1>p2 num>0||p1<p2 num<0 ||p1=p2 num=0
//System.out.println(p1.getAge() +"----"+p2.getAge());
if(num==0) {//次要条件
return p1.getMoney()-p2.getMoney();
}
return num;
}
}
Test测试类
运行后效果
排序效果都一致
思考:
若是项目需求改变了我想要得到又年轻又多金的人怎么办,这时候我们更多用到的是比较器Comparator,自定义一个类来操作,而不是使用comparable——>
案例二:按照多金来排序
使用Comparator,自定义一个PersonMoneyComp 的类
package xml.work;
import java.util.Comparator;
/** * 按照多金来排序
* @author 2019071003
* * */
public class PersonMoneyComp implements Comparator<Person> {
@Override
public int compare(Person o1, Person o2) {
int num=o2.getMoney()-o1.getMoney();
if(num==0) {
return o1.getAge()-o2.getAge();
}
return num;
}
}
成功实现!而且不需要去更改实体类
总结:
共同点:
- 都可以进行排序,都可以自定义比较规则
- 两者都是返回一个描述对象之间关系的int
不同(面试题)
-
Comparable 把自己和另一个对象进行比较
Comparator 比较两个不同的对象 -
· Comparator与Comparable同时存在的情况下,比较器Comparator优先级高。
-
使用Comparable需要修改原先的实体类,是属于一种自然排序,而Comparator 是不用修改原先的类的 。Comparator实际应用广,
(因为在实际开发中,很多时候,引用数据类型是否具有比较性,或者比较规则,可能不由开发人员自己决定,那么开发人员想要对应的引用数据类型按照自己的排序方式进行排列,那么就需要实现comparator接口,实现compare方法 )