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对象描述了一个单独的线程.要产生一个线 ...
随机推荐
- dwz中的(tree)树形菜单的默认收缩
做网站后台时,为了方便管理,可能会用到dwz中的树形菜单,如下: 树形菜单的收缩有默认属性值,可以对其进行一定的初始设定: DWZ的树结构是按<ul>,<li>的嵌套格式构成, ...
- JavaSE复习~基本数据类型
数据类型 java有两大类数据类型:基本数据类型 和 引用数据类型 基本数据类型 整数型:byte.short.int.long 浮点型:float.double 字符型:char 布尔型:boole ...
- Spring Boot Mybatis 使用教程
Mybatis 在当下互联网开发环境,十分重要.本章主要讲述 Mybatis 如何使用. 从本系列开始,都需要用到 mysql 数据库 和其他一些参考的数据库.请准备相关环节.本章需要以下环境支撑: ...
- 寒假pta二
整除光棍 这里所谓的“光棍”,并不是指单身汪啦~ 说的是全部由1组成的数字,比如1.11.111.1111等.传说任何一个光棍都能被一个不以5结尾的奇数整除.比如,111111就可以被13整除. 现在 ...
- Vue中组件之间的通信方式
vue是数据驱动视图更新的框架, 所以对于vue来说组件间的数据通信非常重要,那么组件之间如何进行数据通信的呢? 本文会介绍组件间通信的8种方式如下图所示, 并介绍在不同的场景下如何选择有效方式实现的 ...
- vue 使用心得---工作中一些关键点
1.自定义组件 使用 v-for 循环,最好另外多加上 v-bind:key="items_name",这是特殊用的:key,而不是普通的 :属性 例:<Uiroom> ...
- C++ STL之映射map的使⽤
写在最前面:本文摘录于柳神笔记: map 是键值对,⽐如⼀个⼈名对应⼀个学号,就可以定义⼀个字符串 string 类型的⼈名为“键”,学 号 int 类型为“值”,如 map<string, i ...
- rtt学习之线程间同步与通信
一 线程间的同步与互斥:信号量.互斥量.实践集 线程互斥是指对于临界区资源访问的排它性,如多个线程对共享内存资源的访问,生产消费型对产品的操作.临界区操作操作方法有: rt_hw_interrupt_ ...
- ApacheBench(ab)压力测试工具
服务器负载太大而影响程序效率也是很常见的,Apache服务器自带有一个叫AB(ApacheBench)的工具,可以对服务器进行负载测试 基本用法: ab -n 全部请求数 -c 并发数测试url 注 ...
- bat获取当前路径
@echo off setlocal EnableDelayedExpansion echo 当前正在运行的批处理文件所在路径:!cd! pause @echo off echo 当前目录是:%cd% ...