Java中Compareable和Comparator两种比较器的区别
Java中Compareable和Comparator两种比较器的区别
参考原文链接:https://www.cnblogs.com/ldy-blogs/p/8488138.html
1.引言
在java这个处处是对象的世界里,对两个对象进行按某一属性进行比较是特别常见的需求。比如书店中的书按照价格比较,亦或者是学生按照成绩进行排名等等。
对于JDK8而言,有三种实现对象比较的方法:
1、在需要比较的对象类中覆写Object类的equals()方法;
2、需要比较的类继承Comparable接口,然后在其类内部实现compareTo()方法;
3、抛去需要被比较的类,在其外部自定义一个单独的对象比较器,继承自Comparator接口,实现compare()方法。
由于使用的排序方式的不同,具体选择哪种方法来实现对象的比较也会有所不同。
第一种方法比较便于理解,复写equals()方法一般用于自己实现的对象数组排序,已经在我们上一篇文章 Java的equals方法的使用技巧 中进行了简单介绍,需要了解的朋友可以自行查看。本文我们主要介绍内部比较器compareable和外部比较器comparator两种。
2.内部比较器Compareable的用法
这种方式就是让自己编写的类继承Comparable接口,并实现接口的compareTo()方法,这种情况下,在使用java.util.Arrays.sort()方法时不用指定具体的比较器。
以书店的图书为例,具体实例代码如下:
import java.util.Arrays;
class BookCook implements Comparable<BookCook>{
private String title;
private double price;
public BookCook(String title,double price){
this.title = title;
this.price = price;
}
@Override
public String toString() {
return "书名:"+this.title+",价格:"+this.price;
}
@Override
public int compareTo(BookCook o) {
if(this.price > o.price){
return 1;
}else if(this.price < o.price){
return -1;
}else{
return 0;
}
}
}
在写代码时要注意两点:
(1)时刻要统一比较对象,在这里就是BookCook
(2)在重写的compareTo()方法中,需要特别注意的是,返回值的正负始终与this待比较对象保证同步,即当this值比指定对象大时,就返回正数1,小于时就返回负数-1,相等时就返回0.
3.外部比较器Comparator的用法
从JDK1.8开始出现了Comparator接口,它的出现解决了当需要在已经开发好的代码基础上完善对象的比较功能时不想更改之前的代码的问题。这种情况下,我们就需要单独自定义一个对象比较器,继承Comparator接口。当需要进行比较时,就new一个对象比较器。
以学生成绩为例,具体实现代码如下:
class Student {
private String name;
private double score;
public Student(String name,double score){
this.name = name;
this.score = score;
}
public double getScore(){
return this.score;
}
@Override
public String toString() {
return "姓名:"+this.name+",分数:"+this.score;
}
}
//自定义对象比较器
class StudentComparator implements Comparator<Student> {
@Override
public int compare(Student o1,Student o2) {
if(o1.getScore() > o2.getScore()){
return 1;
}else if(o1.getScore() < o2.getScore()){
return -1;
}else{
return 0;
}
}
}
public class TestComparator {
public static void main(String[] args) {
Student[] sts = new Student[]{
new Student("小戴",60),
new Student("小王",90),
new Student("老王",80),
new Student("小萱",95)
};
//当需要比较功能时,需要在待比较对象后new一个自定义的比较器,以便其按照自定义比较器中的规则进行比较。
java.util.Arrays.sort(sts, new StudentComparator());
System.out.println(java.util.Arrays.toString(sts));
}
}
Java中Compareable和Comparator两种比较器的区别的更多相关文章
- java中Comparable和Comparator两种比较器的区别
Comparable和Comparator接口都是为了对类进行比较,众所周知,诸如Integer,double等基本数据类型,java可以对他们进行比较,而对于类的比较,需要人工定义比较用到的字段比较 ...
- Java中HashMap遍历的两种方式
Java中HashMap遍历的两种方式 转]Java中HashMap遍历的两种方式原文地址: http://www.javaweb.cc/language/java/032291.shtml 第一种: ...
- java中数组复制的两种方式
在java中数组复制有两种方式: 一:System.arraycopy(原数组,开始copy的下标,存放copy内容的数组,开始存放的下标,需要copy的长度); 这个方法需要先创建一个空的存放cop ...
- PHP中数组合并的两种方法及区别介绍
PHP数组合并两种方法及区别 如果是关联数组,如下: 复制代码代码如下: $a = array( 'where' => 'uid=1', 'order' => 'uid', ); $b = ...
- java中设置代理的两种方式
1 前言 有时候我们的程序中要提供可以使用代理访问网络,代理的方式包括http.https.ftp.socks代理.比如在IE浏览器设置代理. 那我们在我们的java程序中使用代理呢,有如下两种方式. ...
- java中创建字符串的两种方式(“”与new String())及区别
结论:通过""创建的字符串实际上在java堆中只有一个,而通过new string创建出来的字符串在java堆中占有不同的内存. 第一个True表明这两个在内存中拥有相同的地址,那 ...
- java中实现同步的两种方式:syschronized和lock的区别和联系
Lock是java.util.concurrent.locks包下的接口,Lock 实现提供了比使用synchronized 方法和语句可获得的更广泛的锁定操作,它能以更优雅的方式处理线程同步问题,我 ...
- 【转载】 Java中String类型的两种创建方式
本文转载自 https://www.cnblogs.com/fguozhu/articles/2661055.html Java中String是一个特殊的包装类数据有两种创建形式: String s ...
- Java中实现多线程的两种方式之间的区别
Java提供了线程类Thread来创建多线程的程序.其实,创建线程与创建普通的类的对象的操作是一样的,而线程就是Thread类或其子类的实例对象.每个Thread对象描述了一个单独的线程.要产生一个线 ...
随机推荐
- QSS基础-设置控件样式
1.QSS基础-设置同类控件样式'''QSS基础:Qt Style SheetQt样式表用于设置控件的样式和风格(比如控件的背景色,字体颜色,字体大小等)和CSS的功能比较相似,功能相似''' fro ...
- cookie,session,localStorage和sessionStorage
cookies:存储于浏览器端的数据.可以设置 cookies 的Max-Age或者Expires到期时间,如果不设置时间,则在浏览器关闭窗口的时候会消失. session:存储于服务器端的数据.se ...
- VUE组件 单独文件封装
https://www.cnblogs.com/SamWeb/p/6391373.html vuejs 单文件组件.vue 文件 vuejs 自定义了一种.vue文件,可以把html, css, ...
- 安装go和goland
1.建议去go语言中文网下载,网址:https://studygolang.com/dl ,下图是下载页面及包介绍 2.Windows版安装 3.在cmd命令行窗口输入“go version”可以查看 ...
- Update(stage3):第1节 redis组件:8、主从复制架构;9、Sentinel架构
8.redis的主从复制架构 在Redis中,用户可以通过执行SLAVEOF命令或者设置slaveof选项,让一个服务器去复制(replicate)另一个服务器,我们称呼被复制的服务器为主服务器(ma ...
- dubbo的dispatcher设置原理
在上回<Dubbo源代码实现六>中我们已经了解到,对于Dubbo集群中的Provider角色,有IO线程池(默认无界)和业务处理线程池(默认200)两个线程池,所以当业务的并发比较高,或者 ...
- python列表操作方法详解
列表 列表是Python中最基本的数据结构,列表是最常用的Python数据类型,列表是一个数据的集合,集合内可以放任何数据类型,可对集合方便的增删改查操作.Python已经内置确定序列的长度以及确 ...
- python去除字符串中的特殊字符(爬虫存储数据时会遇到不能作为文件名的字符串)
问题描述 今天在写爬虫爬取影评时,本来的思路把影评的标题作为文件名,将每个影评的详情内容写入到"标题.txt"文件中,直到我遇到了这个问题: 这时我突然意识到,文件名中有些字符是不 ...
- 8.1.1默认的map函数、reduce函数、分区函数
1.1.1 默认的map函数和reduce函数 (1)Maper和Reuducer默认类 如果没有指定maper类和reduce类,则会用默认的Maper和Reuducer类去处理数据 ...
- java集合体系结构总结
好,首先我们根据这张集合体系图来慢慢分析.大到顶层接口,小到具体实现类. 首先,我想说为什么要用集合?简单的说:数组长度固定,且是同种数据类型.不能满足需求.所以我们引入集合(容器)来存储任意数据类型 ...