java中Comparable和Comparator的区别整理小结
2018-03-28 16:57
453 查看
一、java中,对集合对象或者数组对象排序,有两种实现方式。
总结:
(1)对象实现Comparable接口。
即Comparable 自然排序。(实体类实现)
(2)定义比较器,实现Comparator接口。
即Comparator 是定制排序。(无法修改实体类时,直接在调用方创建)
二、Comparable简介
1.Comparable是排序接口。若一个类实现了Comparable接口,就意味着该类支持排序。实现了Comparable接口的类的对象的列表或数组可以通过Collections.sort或Arrays.sort进行自动排序。
2.Collections.sort (和Arrays.sort )可以自动对实现此接口的对象进行列表(和数组)排序。 实现该接口的对象,可以使用如在键sorted map或作为在元件sorted set ,而不需要指定一个comparator 。
3.若一个类实现了comparable接口,则意味着该类支持排序。如String、Integer自己就实现了Comparable接口,可完成比较大小操作。
一个已经实现comparable的类的对象或数据,可以通过Collections.sort(list) 或者Arrays.sort(arr)实现排序。通过Collections.sort(list,Collections.reverseOrder());对list进行倒序排列。
4.此外,实现此接口的对象可以用作有序映射中的键或有序集合中的集合,无需指定比较器。
Comparable 接口仅仅只包括一个函数,该接口定义如下:
package java.lang;
import java.util.*;
public interface Comparable<T>
{
public int compareTo(T o);
}
T表示可以与此对象进行比较的那些对象的类型。
此接口只有一个方法compare,比较此对象与指定对象的顺序,如果该对象小于、等于或大于指定对象,则分别返回负整数、零或正整数。
5.comparable实例
import java.util.*;
public class test {
public static void main(String[] args) {
List<UserInfo> list = new ArrayList<UserInfo>();
list.add(new UserInfo(1,21,"刘备"));
list.add(new UserInfo(2,27,"曹操"));
list.add(new UserInfo(3,15,"孙权"));
list.add(new UserInfo(5,24,"吕布"));
list.add(new UserInfo(4,24,"张飞"));
//对该类排序
Collections.sort(list);
for(int i=0;i<list.size();i++){
System.out.println(list.get(i));
}
}
}
class UserInfo implements Comparable<UserInfo>{
private int userid;
private int age;
private String name;
public UserInfo(int userid, int age, String name) {
this.userid = userid;
this.age = age;
this.name = name;
}
public int getUserid() {
return userid;
}
public void setUserid(int userid) {
this.userid = userid;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString(){
return this.userid+","+this.age+","+this.name;
}
@Override
public int compareTo(UserInfo o) {
//如果年龄相同,则比较userid,也可以直接 return this.age-o.age;
if(this.age-o.age==0){
return this.userid-o.userid;
}
else{
return this.age-o.age;
}
}
}
输出:
3,15,孙权
1,21,刘备
4,24,张飞
5,24,吕布
2,27,曹操
三、Comparator简介
1.Comparator是比较接口,我们如果需要控制某个类的次序,而该类本身不支持排序(即没有实现Comparable接口),那么我们就可以建立一个“该类的比较器”来进行排序,这个“比较器”只需要实现Comparator接口即可。也就是说,我们可以通过实现Comparator来新建一个比较器,然后通过这个比较器对类进行排序。
2.如果引用的为第三方jar包,这时候,没办法改变类本身,可是使用这种方式。
Comparator是一个专用的比较器,当这个对象不支持自比较或者自比较函数不能满足要求时,可写一个比较器来完成两个对象之间大小的比较。
Comparator体现了一种策略模式(strategy design pattern),就是不改变对象自身,而用一个策略对象(strategy object)来改变它的行为。
3.该接口定义如下:
package java.util;
public interface Comparator<T>
{
int compare(T o1, T o2);
boolean equals(Object obj);
}
注意:
(1)若一个类要实现Comparator接口:它一定要实现compare(T o1,T o2) 函数,但可以不实现equals(Object obj)函数。
(2)int compare(T o1,T o2) 是“比较o1和o2的大小”。返回“负数”,意味着“o1比o2小”;返回“零”,意味着“o1等于o2”;返回“正数”,意味着“o1大于o2”。
4.comparator实例
import java.util.*; //直接这样写,比下面四条语句简洁
//import java.util.ArrayList;
//import java.util.Collections;
//import java.util.List;
//import java.util.Comparator;
public class day6 {
public static void main(String[] args) {
List<UserInfo> list = new ArrayList<UserInfo>();
list.add(new UserInfo(1,21,"刘备"));
list.add(new UserInfo(2,27,"曹操"));
list.add(new UserInfo(3,15,"孙权"));
list.add(new UserInfo(5,24,"吕布"));
list.add(new UserInfo(4,24,"张飞"));
//new一个比较器
MyComparator comparator = new MyComparator();
//对list排序
Collections.sort(list,comparator);
for(int i=0;i<list.size();i++){
System.out.println(list.get(i));
}
}
}
class MyComparator implements Comparator<UserInfo>{
@Override
public int compare(UserInfo o1,UserInfo o2) {
if(o1.getAge()-o2.getAge()==0){
return o1.getUserid()-o2.getUserid();
}
else{
return o1.getAge()-o2.getAge();
}
}
}
class UserInfo{
private int userid;
private int age;
private String name;
public UserInfo(int userid, int age, String name) {
this.userid = userid;
this.age = age;
this.name = name;
}
public int getUserid() {
return userid;
}
public void setUserid(int userid) {
this.userid = userid;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString(){
return this.userid+","+this.age+","+this.name;
}
}
输出:
3,15,孙权
1,21,刘备
4,24,张飞
5,24,吕布
2,27,曹操
5. Comparator使用方式主要分三步:
(1)创建一个Comparator接口的实现类,并赋值给一个对象
在compare方法中针对自定义类写排序规则
(2)将Comparator对象作为参数传递给 排序类的某个方法
(3)向排序类中添加 compare 方法中使用的自定义类
即举个例子:
// 1.创建一个实现 Comparator 接口的对象
Comparator comparator = new Comparator()
//2.将此对象作为形参传递给 TreeSet 的构造器中
TreeSet treeSet = new TreeSet(comparator);
//3.向 TreeSet 中添加 步骤 1 中 compare 方法中设计的类的对象
treeSet.add(new NewBookBean("A",34));
treeSet.add(new NewBookBean("S",1));
四、Comparable和Comparator整体实例
import java.util.*;
public class day6 {
public static void main(String[] args){
List<Node> list = new ArrayList<Node>();
list.add(new Node("关羽",25));
list.add(new Node("赵云",22));
list.add(new Node("甘宁",20));
list.add(new Node("张辽",23));
System.out.println("Comparator--年龄排序===");
Collections.sort(list, new Comparator<Node>() {
@Override
public int compare(Node o1, Node o2) {
return o1.getAge()-o2.getAge();
}
});
for(Iterator<Node> it = list.iterator(); it.hasNext();){
System.out.println(it.next());
}
System.out.println("Comparator--姓名排序===");
Collections.sort(list, new Comparator<Node>() {
@Override
public int compare(Node o1, Node o2) {
return o1.getName().compareTo(o2.getName());
}
});
for(Iterator<Node> it = list.iterator(); it.hasNext();){
System.out.println(it.next());
}
System.out.println("Comparable--年龄排序...");
Collections.sort(list);
for(Iterator<Node> it = list.iterator(); it.hasNext();){
System.out.println(it.next());
}
}
}
class Node implements Comparable<Node>{
private String name;
private int age;
public Node(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;
}
public int compareTo(Node other){
if(age > other.getAge())
return -1;
if(age < other.getAge())
return 1;
return 0;
}
public String toString(){
return "姓名 "+name+" 年龄 "+age;
}
}
输出:
Comparator--年龄排序===
姓名 甘宁 年龄 20
姓名 赵云 年龄 22
姓名 张辽 年龄 23
姓名 关羽 年龄 25
Comparator--姓名排序===
姓名 关羽 年龄 25
姓名 张辽 年龄 23
姓名 甘宁 年龄 20
姓名 赵云 年龄 22
Comparable--年龄排序...
姓名 关羽 年龄 25
姓名 张辽 年龄 23
姓名 赵云 年龄 22
姓名 甘宁 年龄 20
五、补充
1.Comparable 是排序接口;若一个类实现了 Comparable 接口,就意味着 “该类支持排序”。而 Comparator 是比较器;我们若需要控制某个类的次序,可以建立一个 “该类的比较器” 来进行排序。
前者应该比较固定,和一个具体类相绑定,而后者比较灵活,它可以被用于各个需要比较功能的类使用。可以说前者属于 “静态绑定”,而后者可以 “动态绑定”。
我们不难发现:Comparable 相当于 “内部比较器”,而 Comparator 相当于 “外部比较器”。
2.对于一些普通的数据类型(比如 String, Integer, Double…),它们默认实现了Comparable 接口,实现了 compareTo 方法,我们可以直接使用。
而对于一些自定义类,它们可能在不同情况下需要实现不同的比较策略,我们可以新创建 Comparator 接口,然后使用特定的 Comparator 实现进行比较。
3.两种方法各有优劣, 用Comparable 简单, 只要实现Comparable 接口的对象直接就成为一个可以比较的对象,但是需要修改源代码。 用Comparator 的好处是不需要修改源代码, 而是另外实现一个比较器, 当某个自定义的对象需要作比较的时候,把比较器和对象一起传递过去就可以比大小了, 并且在Comparator 里面用户可以自己实现复杂的可以通用的逻辑,使其可以匹配一些比较简单的对象,那样就可以节省很多重复劳动了。
本篇博文是小白我在大神的肩膀上,吸收整理出来的。衷心感谢大神们的无私奉献、厚薄积发的精神,这种品质给我们小白在技术上的成长带来了很大的帮助。
参考: https://blog.csdn.net/tolcf/article/details/52229068 https://blog.csdn.net/yguoelect/article/details/77435073
总结:
(1)对象实现Comparable接口。
即Comparable 自然排序。(实体类实现)
(2)定义比较器,实现Comparator接口。
即Comparator 是定制排序。(无法修改实体类时,直接在调用方创建)
二、Comparable简介
1.Comparable是排序接口。若一个类实现了Comparable接口,就意味着该类支持排序。实现了Comparable接口的类的对象的列表或数组可以通过Collections.sort或Arrays.sort进行自动排序。
2.Collections.sort (和Arrays.sort )可以自动对实现此接口的对象进行列表(和数组)排序。 实现该接口的对象,可以使用如在键sorted map或作为在元件sorted set ,而不需要指定一个comparator 。
3.若一个类实现了comparable接口,则意味着该类支持排序。如String、Integer自己就实现了Comparable接口,可完成比较大小操作。
一个已经实现comparable的类的对象或数据,可以通过Collections.sort(list) 或者Arrays.sort(arr)实现排序。通过Collections.sort(list,Collections.reverseOrder());对list进行倒序排列。
4.此外,实现此接口的对象可以用作有序映射中的键或有序集合中的集合,无需指定比较器。
Comparable 接口仅仅只包括一个函数,该接口定义如下:
package java.lang;
import java.util.*;
public interface Comparable<T>
{
public int compareTo(T o);
}
T表示可以与此对象进行比较的那些对象的类型。
此接口只有一个方法compare,比较此对象与指定对象的顺序,如果该对象小于、等于或大于指定对象,则分别返回负整数、零或正整数。
5.comparable实例
import java.util.*;
public class test {
public static void main(String[] args) {
List<UserInfo> list = new ArrayList<UserInfo>();
list.add(new UserInfo(1,21,"刘备"));
list.add(new UserInfo(2,27,"曹操"));
list.add(new UserInfo(3,15,"孙权"));
list.add(new UserInfo(5,24,"吕布"));
list.add(new UserInfo(4,24,"张飞"));
//对该类排序
Collections.sort(list);
for(int i=0;i<list.size();i++){
System.out.println(list.get(i));
}
}
}
class UserInfo implements Comparable<UserInfo>{
private int userid;
private int age;
private String name;
public UserInfo(int userid, int age, String name) {
this.userid = userid;
this.age = age;
this.name = name;
}
public int getUserid() {
return userid;
}
public void setUserid(int userid) {
this.userid = userid;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString(){
return this.userid+","+this.age+","+this.name;
}
@Override
public int compareTo(UserInfo o) {
//如果年龄相同,则比较userid,也可以直接 return this.age-o.age;
if(this.age-o.age==0){
return this.userid-o.userid;
}
else{
return this.age-o.age;
}
}
}
输出:
3,15,孙权
1,21,刘备
4,24,张飞
5,24,吕布
2,27,曹操
三、Comparator简介
1.Comparator是比较接口,我们如果需要控制某个类的次序,而该类本身不支持排序(即没有实现Comparable接口),那么我们就可以建立一个“该类的比较器”来进行排序,这个“比较器”只需要实现Comparator接口即可。也就是说,我们可以通过实现Comparator来新建一个比较器,然后通过这个比较器对类进行排序。
2.如果引用的为第三方jar包,这时候,没办法改变类本身,可是使用这种方式。
Comparator是一个专用的比较器,当这个对象不支持自比较或者自比较函数不能满足要求时,可写一个比较器来完成两个对象之间大小的比较。
Comparator体现了一种策略模式(strategy design pattern),就是不改变对象自身,而用一个策略对象(strategy object)来改变它的行为。
3.该接口定义如下:
package java.util;
public interface Comparator<T>
{
int compare(T o1, T o2);
boolean equals(Object obj);
}
注意:
(1)若一个类要实现Comparator接口:它一定要实现compare(T o1,T o2) 函数,但可以不实现equals(Object obj)函数。
(2)int compare(T o1,T o2) 是“比较o1和o2的大小”。返回“负数”,意味着“o1比o2小”;返回“零”,意味着“o1等于o2”;返回“正数”,意味着“o1大于o2”。
4.comparator实例
import java.util.*; //直接这样写,比下面四条语句简洁
//import java.util.ArrayList;
//import java.util.Collections;
//import java.util.List;
//import java.util.Comparator;
public class day6 {
public static void main(String[] args) {
List<UserInfo> list = new ArrayList<UserInfo>();
list.add(new UserInfo(1,21,"刘备"));
list.add(new UserInfo(2,27,"曹操"));
list.add(new UserInfo(3,15,"孙权"));
list.add(new UserInfo(5,24,"吕布"));
list.add(new UserInfo(4,24,"张飞"));
//new一个比较器
MyComparator comparator = new MyComparator();
//对list排序
Collections.sort(list,comparator);
for(int i=0;i<list.size();i++){
System.out.println(list.get(i));
}
}
}
class MyComparator implements Comparator<UserInfo>{
@Override
public int compare(UserInfo o1,UserInfo o2) {
if(o1.getAge()-o2.getAge()==0){
return o1.getUserid()-o2.getUserid();
}
else{
return o1.getAge()-o2.getAge();
}
}
}
class UserInfo{
private int userid;
private int age;
private String name;
public UserInfo(int userid, int age, String name) {
this.userid = userid;
this.age = age;
this.name = name;
}
public int getUserid() {
return userid;
}
public void setUserid(int userid) {
this.userid = userid;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString(){
return this.userid+","+this.age+","+this.name;
}
}
输出:
3,15,孙权
1,21,刘备
4,24,张飞
5,24,吕布
2,27,曹操
5. Comparator使用方式主要分三步:
(1)创建一个Comparator接口的实现类,并赋值给一个对象
在compare方法中针对自定义类写排序规则
(2)将Comparator对象作为参数传递给 排序类的某个方法
(3)向排序类中添加 compare 方法中使用的自定义类
即举个例子:
// 1.创建一个实现 Comparator 接口的对象
Comparator comparator = new Comparator()
//2.将此对象作为形参传递给 TreeSet 的构造器中
TreeSet treeSet = new TreeSet(comparator);
//3.向 TreeSet 中添加 步骤 1 中 compare 方法中设计的类的对象
treeSet.add(new NewBookBean("A",34));
treeSet.add(new NewBookBean("S",1));
四、Comparable和Comparator整体实例
import java.util.*;
public class day6 {
public static void main(String[] args){
List<Node> list = new ArrayList<Node>();
list.add(new Node("关羽",25));
list.add(new Node("赵云",22));
list.add(new Node("甘宁",20));
list.add(new Node("张辽",23));
System.out.println("Comparator--年龄排序===");
Collections.sort(list, new Comparator<Node>() {
@Override
public int compare(Node o1, Node o2) {
return o1.getAge()-o2.getAge();
}
});
for(Iterator<Node> it = list.iterator(); it.hasNext();){
System.out.println(it.next());
}
System.out.println("Comparator--姓名排序===");
Collections.sort(list, new Comparator<Node>() {
@Override
public int compare(Node o1, Node o2) {
return o1.getName().compareTo(o2.getName());
}
});
for(Iterator<Node> it = list.iterator(); it.hasNext();){
System.out.println(it.next());
}
System.out.println("Comparable--年龄排序...");
Collections.sort(list);
for(Iterator<Node> it = list.iterator(); it.hasNext();){
System.out.println(it.next());
}
}
}
class Node implements Comparable<Node>{
private String name;
private int age;
public Node(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;
}
public int compareTo(Node other){
if(age > other.getAge())
return -1;
if(age < other.getAge())
return 1;
return 0;
}
public String toString(){
return "姓名 "+name+" 年龄 "+age;
}
}
输出:
Comparator--年龄排序===
姓名 甘宁 年龄 20
姓名 赵云 年龄 22
姓名 张辽 年龄 23
姓名 关羽 年龄 25
Comparator--姓名排序===
姓名 关羽 年龄 25
姓名 张辽 年龄 23
姓名 甘宁 年龄 20
姓名 赵云 年龄 22
Comparable--年龄排序...
姓名 关羽 年龄 25
姓名 张辽 年龄 23
姓名 赵云 年龄 22
姓名 甘宁 年龄 20
五、补充
1.Comparable 是排序接口;若一个类实现了 Comparable 接口,就意味着 “该类支持排序”。而 Comparator 是比较器;我们若需要控制某个类的次序,可以建立一个 “该类的比较器” 来进行排序。
前者应该比较固定,和一个具体类相绑定,而后者比较灵活,它可以被用于各个需要比较功能的类使用。可以说前者属于 “静态绑定”,而后者可以 “动态绑定”。
我们不难发现:Comparable 相当于 “内部比较器”,而 Comparator 相当于 “外部比较器”。
2.对于一些普通的数据类型(比如 String, Integer, Double…),它们默认实现了Comparable 接口,实现了 compareTo 方法,我们可以直接使用。
而对于一些自定义类,它们可能在不同情况下需要实现不同的比较策略,我们可以新创建 Comparator 接口,然后使用特定的 Comparator 实现进行比较。
3.两种方法各有优劣, 用Comparable 简单, 只要实现Comparable 接口的对象直接就成为一个可以比较的对象,但是需要修改源代码。 用Comparator 的好处是不需要修改源代码, 而是另外实现一个比较器, 当某个自定义的对象需要作比较的时候,把比较器和对象一起传递过去就可以比大小了, 并且在Comparator 里面用户可以自己实现复杂的可以通用的逻辑,使其可以匹配一些比较简单的对象,那样就可以节省很多重复劳动了。
本篇博文是小白我在大神的肩膀上,吸收整理出来的。衷心感谢大神们的无私奉献、厚薄积发的精神,这种品质给我们小白在技术上的成长带来了很大的帮助。
参考: https://blog.csdn.net/tolcf/article/details/52229068 https://blog.csdn.net/yguoelect/article/details/77435073
相关文章推荐
- Java中Comparable和Comparator区别小结
- Java中Comparable和Comparator区别小结
- Java中Comparable和Comparator区别小结
- 【java】Comparable和Comparator区别小结
- Java中 Comparator接口 与Comparable 的区别
- Java学习之Comparable与Comparator的区别
- Java中的Comparable与Comparator的区别
- Java 解惑:Comparable 和 Comparator 的区别
- Java中Comparable与Comparator的区别
- OpenJDK源码研究笔记(二)-Comparable和Comparator2个接口的作用和区别(一道经典的Java笔试面试题)
- Java 解惑:Comparable 和 Comparator 的区别
- Java--comparator接口与Comparable接口的区别
- java comparator接口与Comparable接口的区别
- java比较器Comparator 和 Comparable 的区别
- java Comparable 和Comparator 详解及区别
- java Comparable 和Comparator详解及 区别(附代码)
- java Comparable接口与Comparator接口使用小结
- 接口 Comparable与Comparator的区别 (Java)
- Java之Comparable与Comparator的区别
- 浅析Java中comparator接口与Comparable接口的区别