Java集合相关学习——元素排序两大接口Comparable和Comparator的应用及区别
Posted 张起灵-小哥
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java集合相关学习——元素排序两大接口Comparable和Comparator的应用及区别相关的知识,希望对你有一定的参考价值。
1.引出话题
在 Java 语言中,Comparable 和 Comparator 都是用来进行元素排序的,但二者有着本质的区别。
2.Comparable
Comparable 接口只有一个方法 compareTo,实现 Comparable 接口并重写 compareTo 方法就可以实现某个类的排序了,它支持 Collections.sort 和 Arrays.sort 的排序。
Comparable 的使用是在自定义对象的类中实现 Comparable 接口,并重写 compareTo 方法来实现自定义排序规则的,compareTo 方法接收的参数 p 是要对比的对象,排序规则是用当前对象和要对比的对象进行比较,然后返回一个 int 类型的值。正序从小到大的排序规则是:使用当前的对象值减去要对比对象的值;而倒序从大到小的排序规则刚好相反:是用对比对象的值减去当前对象的值。
具体实现代码如下:
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.*;
import java.util.Map;
/**
*
*/
class Man implements Comparable<Man>
private Integer id;
private String name;
private Integer age;
public Man(Integer id, String name, Integer age)
this.id = id;
this.name = name;
this.age = age;
public Integer getId()
return id;
public void setId(Integer id)
this.id = id;
public String getName()
return name;
public void setName(String name)
this.name = name;
public Integer getAge()
return age;
public void setAge(Integer age)
this.age = age;
@Override
public int compareTo(Man m)
return m.getAge() - this.getAge();
@Override
public String toString()
return "Man" +
"id=" + id +
", name='" + name + '\\'' +
", age=" + age +
'';
public class ComparableTest
public static void main(String[] args)
List<Man> list = new ArrayList<>();
list.add(new Man(1, "张起灵", 18));
list.add(new Man(2, "小哥", 22));
list.add(new Man(3, "闷油瓶", 20));
Collections.sort(list);
list.forEach(System.out::println);
3.Comparator
Comparator 和 Comparable 的排序方法是不同的,Comparable 排序的方法是 compareTo,而 Comparator 排序的方法是 compare,具体实现代码如下:
import java.util.*;
import java.util.Map;
/**
*
*/
class Man2 implements Comparable<Man>
private String name;
private Integer age;
public Man2(String name, Integer age)
this.name = name;
this.age = age;
public String getName()
return name;
public void setName(String name)
this.name = name;
public Integer getAge()
return age;
public void setAge(Integer age)
this.age = age;
@Override
public int compareTo(Man m)
return m.getAge() - this.getAge();
@Override
public String toString()
return "Man2" +
"name='" + name + '\\'' +
", age=" + age +
'';
public class ComparatorTest
private static Map<Integer, Man2> sortMap(Map<Integer, Man2> map)
//首先拿到 map 的键值对集合
Set<Map.Entry<Integer, Man2>> entrySet = map.entrySet();
//将 set 集合转为 List 集合,原因:为了使用工具类的排序方法
List<Map.Entry<Integer, Man2>> list = new ArrayList<>(entrySet);
//使用 Collections 集合工具类对 list 进行排序,排序规则使用匿名内部类来实现
Collections.sort(list, new Comparator<Map.Entry<Integer, Man2>>()
@Override
public int compare(Map.Entry<Integer, Man2> o1, Map.Entry<Integer, Man2> o2)
//自定义按照年龄的降序排序
return o2.getValue().getAge() - o1.getValue().getAge();
);
//创建一个新的有序的Map集合
Map<Integer, Man2> linkedHashMap = new LinkedHashMap<>();
//将 List 中的数据存储在 LinkedHashMap 中
list.forEach(m ->
linkedHashMap.put(m.getKey(), m.getValue());
);
return linkedHashMap;
public static void main(String[] args)
Map<Integer, Man2> map = new HashMap<>();
map.put(1, new Man2("张起灵", 18));
map.put(2, new Man2("小哥", 22));
map.put(3, new Man2("闷油瓶", 20));
System.out.println("排序之前的map集合为:\\n" + map);
System.out.println("-------------------------------");
Map<Integer, Man2> sortMap = sortMap(map);
System.out.println("排序之后的map集合为:\\n" + sortMap);
4.对比二者
通过上面示例的实现代码我们可以看出,使用 Comparable 必须要修改原有的类,也就是你要排序那个类,就要在那个中实现 Comparable 接口并重写 compareTo 方法,所以 Comparable 更像是“对内”进行排序的接口。
而 Comparator 的使用则不相同,Comparator 无需修改原有类。也就是在最极端情况下,即使 Person 类是第三方提供的,我们依然可以通过创建新的自定义比较器 Comparator,来实现对第三方类 Person 的排序功能。也就是说通过 Comparator 接口可以实现和原有类的解耦,在不修改原有类的情况下实现排序功能,所以 Comparator 可以看作是“对外”提供排序的接口。
Comparable 和 Comparator 都是用来实现元素排序的,它们二者的区别如下:
Comparable 是“比较”的意思,而 Comparator 是“比较器”的意思;
Comparable 是通过重写 compareTo 方法实现排序的,而 Comparator 是通过重写 compare 方法实现排序的;
Comparable 必须由自定义类内部实现排序方法,而 Comparator 是外部定义并实现排序的。
所以用一句话总结二者的区别:Comparable 可以看作是“对内”进行排序接口,而 Comparator 是“对外”进行排序的接口。
以上是关于Java集合相关学习——元素排序两大接口Comparable和Comparator的应用及区别的主要内容,如果未能解决你的问题,请参考以下文章
Java学习之Comparable与Comparator的区别