您的位置:首页 > 编程语言 > Java开发

java Comparable接口与Comparator接口的使用与区别

2017-09-09 17:18 573 查看

一、[b]Comparable 接口的使用[/b]

Comparable 这个接口对实现它的每个类的对象施加了一个总的排序。这个顺序被称为类的自然排序,和类的compareTo方法称为自然方法。

 实现这个接口的可以自动排序的对象列表(list<>)或数组(Object[])可以通过 Collections.sort()或Arrays.sort()方法进行排序。

实现此接口的对象中的元素可以作为排序集中的进行比较的键,而不需要指定比较器。(上述为翻译API中的一段话)。

因为刚好用到排序,并且是需要对整体进行排序可以使用 Comparable  接口。

1、需要进行排序的 pojo 对象需要实现  Comparable  接口,实现自定义的排序方法。

最终的目的:对  Staff 对象,按照对象的年龄属性,与KPI属性的大小进行排序。年龄大的排在前面,年龄相同的 则KPI 高的排在前面

package comparable_test;

/**
* 员工实体
* @author Scott
* @time 2017年9月9日
*/
public class Staff implements Comparable<Staff>{

/** 员工年龄*/
private int age;
/** 员工KPI*/
private int score;

/**
* 构造函数
* @param age
* @param score
*/
public Staff(int age, int score) {
super();
this.age = age;
this.score = score;
}

//比较对象大小时以 参数 作为基准
@Override
public int compareTo(Staff o) {
int i = 0;
if (o.age > this.age) {
i = 1;
} else if (this.age == o.age) {
if (o.score > this.score) {
i = 1;
} else if (o.score < this.score) {
i = -1;
}
} else if (o.age < this.age) {
i = -1;
}
return i;
}

//get set ...

public int getScore() {
return score;
}

public void setScore(int score) {
this.score = score;
}

public int getAge() {
return age;
}

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




2、使用Collections.sort()方法进行整体排序,并输出排序前后的结果

此时是不许要指定一个比较器的
package comparable_test;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class TestSort {

static List<Staff> staffInfos = new ArrayList<Staff>();
public static void main(String[] args) {

staffInfos.add(new Staff(5, 102));
staffInfos.add(new Staff(8, 103));
staffInfos.add(new Staff(4, 104));
staffInfos.add(new Staff(4, 105));

//排序前输出结果
System.out.println("排序前输出结果");
staffInfos.forEach(staff -> {
int age = staff.getAge();
int score = staff.getScore();
System.out.println("年龄:"+ age + "\t\t" + "KPI:" + score);
});

//排序后输出结果
System.out.println("\n"+"排序后输出结果");
Collections.sort(staffInfos);
staffInfos.forEach(staff -> {
int age = staff.getAge();
int score = staff.getScore();
System.out.println("年龄:"+ age + "\t\t" + "KPI:" + score);
});

}
}

3、排序前后输出结果对比

排序前输出结果

年龄:5 KPI:102

年龄:8 KPI:103

年龄:4 KPI:104

年龄:4 KPI:105

排序后输出结果

年龄:8 KPI:103

年龄:5 KPI:102

年龄:4 KPI:105

年龄:4 KPI:104


通过上面的排序前后的输出结果看到,已经实现了之前的目的了。只要pojo类实现了 Comparable  接口,如果是 List<> 则使用 Collections.sort(); 方法进行排序。如果是Staff[]数组,则使用Arrays.sort()进行排序。
这里面说明一下:使用 Comparable 接口实现整体排序时,需要注意的是排序是以被实现的  compareTo () 方法中的参数为基准的。具体请各位读者自己测试。

二、Comparator接口的使用

1、需要进行整体排序的对象如下
package comparable_test;

/**
* 员工实体
* @author Scott
* @time 2017年9月9日
*/
public class Staff {

/** 员工年龄*/
private int age;
/** 员工KPI*/
private int score;

/**
* 构造函数
* @param age
* @param score
*/
public Staff(int age, int score) {
super();
this.age = age;
this.score = score;
}

//get set ...

public int getScore() {
return score;
}

public void setScore(int score) {
this.score = score;
}

public int getAge() {
return age;
}

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

2、使用 Comparator 接口对上面的 staff 进行整体排序

在使用 Comparator 接口实现整体排序时,需要实现自定义的比较器。
在使用 Collections.sort()或Arrays.sort() 进行排序时需要指定使用哪个比较器

package comparable_test;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
/**
* 测试类
* @author Scott
* @time 2017年9月11日
*/
public class TestSort {

/** Staff 列表*/
static List<Staff> staffInfos = new ArrayList<Staff>();

public static void main(String[] args) {
staffInfos.add(new Staff(5, 102));
staffInfos.add(new Staff(8, 103));
staffInfos.add(new Staff(4, 104));
staffInfos.add(new Staff(4, 105));
//排序前输出结果
System.out.println("排序前输出结果");
staffInfos.forEach(staff -> {
int age = staff.getAge();
int score = staff.getScore();
System.out.println("年龄:"+ age + "\t\t" + "KPI:" + score);
});

//使用  Comparator 构造自定义比较器
Comparator<Staff> comparaor = new Comparator<Staff>() {
@Override
public int compare(Staff o1, Staff o2) {
int i = 0;
if (o2.getAge() > o1.getAge()) {
i = 1;
} else if (o2.getAge() == o1.getAge()) {
if (o2.getScore() > o1.getScore()) {
i = 1;
} else if (o2.getScore() < o1.getScore()) {
i = -1;
}
} else if (o2.getAge() < o1.getAge()) {
i = -1;
}
return i;
}
};
//进行排序,第二个参数是指定使用的比较器
Collections.sort(staffInfos, comparaor);

//排序后输出结果
System.out.println("\n"+"排序后输出结果");
staffInfos.forEach(staff -> {
int age = staff.getAge();
int score = staff.getScore();
System.out.println("年龄:"+ age + "\t\t" + "KPI:" + score);
});
}
}


3、使用 Comparator 进行整体排序的输出结果

排序前输出结果

年龄:5 KPI:102

年龄:8 KPI:103

年龄:4 KPI:104

年龄:4 KPI:105

排序后输出结果

年龄:8 KPI:103

年龄:5 KPI:102

年龄:4 KPI:105

年龄:4 KPI:104

三、使用 Comparable 与 Comparator 两者的区别

从上面两个简答的使用例子中可以发现:
使用 Comparable 与 Comparator 两者的区别是:
 * 1、使用 Comparable 在需要进行整体排序的类中 需要实现 Comparable 接口,实现接口中的 compareTo() 方法(比较器)。使用 Comparator 则不需要实现任何接口

 * 2、使用 Comparator 需要自定义比较器,在排序时(使用Collections.sort()方法进行排序)需要指定比较器。而使用 Comparable 接口在排序时则不需要指定比较器
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐