java常用类——比较器
Comparable和Comparator接口都是为了对类进行比较,众所周知,诸如Integer,double等基本数据类型,java可以对他们进行比较,而对于类的比较,需要人工定义比较用到的字段比较逻辑。可以把Comparable理解为内部比较器,而Comparator是外部比较器,基本的写法如下:
class Apple implements Comparable<Apple>{
int id;
double price;
public Apple(int id, double price) {
this.id = id;
this.price = price;
}
public int compareTo(Apple o) {
//return Double.compare(this.getPrice(),o.getPrice());
if (Math.abs(this.price-o.price)<0.001)
return 0;
else
return (o.price-this.price)>0?1:-1;
}
@Override
public String toString() {
return "Apple{" +
"id=" + id +
", price=" + price +
'}';
}
}
class AESComparator implements Comparator<Apple>{
public int compare(Apple o1, Apple o2) {
if (Math.abs(o1.price-o2.price)<0.001)
return 0;
else{
return (o1.price-o2.price)>0?1:-1;
}
}
}
实现了Comparable接口的类需要实现compareTo()方法,传入一个外部参数进行比对,实现了Comparator接口的方法需要实现compare()方法,对外部传入的两个类进行比较,从而让外部方法在比较时调用。
两者的区别是实现Comparator接口代码更加灵活,可以定义某个类的多个比较器,从而在排序时根据实际场景自由调用,而Comparable接口实现后便不能改动。
总结:
comparator接口:真正要实现的只有compare()方法,需要单独准备出一个类来实现comparator接口,这个类将作为指定类的排序类
public int compare(Emp o1,Emp,o2){
return o1.id - o2.id
}
这是说如果o1的id - o2的id是正数就升序,如果负数降序。如果0就剔除
>=1 升序
<=-1 降序
=0 重复,不记录
comparable接口
实现该类接口不需要重新创建一个排序的类,使用接口compareble接口排序,只要重写里面的compareTo()方法
Collections类是一个包装类,它包含有各种有关集合操作的静态方法。就像一个工具类。
Collections.sort()
sort()排序方法,根据元素的自然排序对指定列表按升序进行排序
public static <T>void sort(List<T> list,Comparator<>),根据指定比较器产生的顺序对指定列表进行排序,此列表内的所有元素都必须可使用指定的比较器相互比较
参数:list——要排序的列表
C——确定列表顺序的比较器
在Java中经常会涉及到对象数组的排序问题,那么就涉及到对象之间的比较问题。
通常对象之间的比较可以从两个方面去看:
第一个方面:对象的地址是否一样,也就是是否引用自同一个对象。这种方式可以直接使用“==“来完成。
第二个方面:以对象的某一个属性的角度去比较。
从最新的JDK8而言,有三种实现对象比较的方法:
一、覆写Object类的equals()方法;
二、继承Comparable接口,并实现compareTo()方法;
三、定义一个单独的对象比较器,继承自Comparator接口,实现compare()方法。
由于使用的排序方式的不同,具体选择哪种方法来实现对象的比较也会有所不同。
覆写equals()方法,一般用于自己实现对象数组排序的情况,而对于要使用java内置的排序算法时,使用后面两种方式都是可行的。
先来看第二种方式,这种方式就是让自己编写的类继承Comparable接口,并实现compareTo()方法,这种情况下,在使用java.util.Arrays.sort()
方法时,不用指定具体的比较器,sort()方法会使用对象自己的比较函数来完成对象的排序。下面是一个具体的例子:
[java] view plain copy
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;
}
}
}
一般我们使用以上两种方法就能够满足实际的开发问题。但是当出现以下情况时,就需要用到Comparator接口:
要在已经开发好的代码的基础上完善对象的比较功能时,又不想更改之前的代码,这种情况下,从JDK1.8之后出现了Comparator接口,是对这种情况的一个弥补。
这种情况下,我们需要单独定义一个对象比较器,继承Comparator接口,并实现compare()方法。示例代码如下:
[java] view plain copy
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)
};
java.util.Arrays.sort(sts, new StudentComparator());
System.out.println(java.util.Arrays.toString(sts));
}
}
Java中存在比较运算符:> 、< 、>=、<=、!=、==、instanceof
只能比较基本数据类型,如果对于对象无法进行比较,如果在对象中需要实现对象之间的比较,只能通过Comparable、Compartor接口实现
(1) Comparable接口(自然排序)
String、包装类都已经默认实现了mt4下载教程Comparable接口,并重写了int compareTo(T o)方法(定义排序规则),所以String、包装类都是可以进行排序的
默认是按照升序进行排序的
int compareTo(T o)
如果返回值是正数,代表调用者(this)的值比o的值要大
如果返回值是负数,代表调用者(this)的值比o的值要小
如果返回值是0,代表调用者(this)的值比o的值相等
如果一个自定义类需要实现排序功能,需要让当前类实现Comparable接口,重写int compareTo(T o)方法,在该方法中重写排序的规则
如果一个类一旦实现了Comparable接口,那么这个类的对象在任意地方都可以进行排序或者比较
/*
String、包装类都已经默认实现了Comparable接口,并重写了int compareTo(T o)方法
*/
public class CompareDemo {
public static void main(String[] args) {
int[] arr = {5,4,2,1,3};
Arrays.sort(arr);
System.out.println(Arrays.toString(arr));
String[] s = {"AA","CC","ZZ","BB","JJ"};
Arrays.sort(s);
System.out.println(Arrays.toString(s));
}
}
/*
对象之间比较
*/
public class CompareDemo {
public static void main(String[] args) {
Employee[] e = new Employee[5];
e[0] = new Employee("e001","Jack","d001");
e[1] = new Employee("e005","Tom","d010");
e[2] = new Employee("e010","Jack","d011");
e[3] = new Employee("e004","Rose","d005");
e[4] = new Employee("e009","Marry","d008");
Arrays.sort(e);
System.out.println(Arrays.toString(e));
}
}
class Employee implements Comparable<Employee>{
private String eno;
private String ename;
private String dept;
public String getEno() {
return eno;
}
public void setEno(String eno) {
this.eno = eno;
}
public String getEname() {
return ename;
}
public void setEname(String ename) {
this.ename = ename;
}
public String getDept() {
return dept;
}
public void setDept(String dept) {
this.dept = dept;
}
public Employee(String eno, String ename, String dept) {
super();
this.eno = eno;
this.ename = ename;
this.dept = dept;
}
public Employee() {
super();
}
@Override
public String toString() {
return "Employee [eno=" + eno + ", ename=" + ename + ", dept=" + dept + "]";
}
@Override
public int compareTo(Employee o) {
//借助String的compareTo方法
return this.eno.compareTo(o.eno);
}
}
(2)Comparator接口(定制排序)
如果一个类没有实现Comparable接口,但是这个类又不方便实现Comparable接口(开闭原则),或者一个类已经实现了Comparable接口,但是其中的compareTo不满足我们的需求,那么我们可以使用Comparator接口方式进行定制排序
默认升序
int compare(T o1,T o2)
o1>o2 返回正数
o1<o2 返回负数
o1==o2 返回0
public class CompareDemo {
public static void main(String[] args) {
Employee[] e = new Employee[5];
e[0] = new Employee("e001","Jack","d001");
e[1] = new Employee("e003","Tom","d010");
e[2] = new Employee("e003","Jack","d011");
e[3] = new Employee("e004","Rose","d005");
e[4] = new Employee("e002","Marry","d008");
Arrays.sort(e, new Comparator<Employee>() {
@Override
public int compare(Employee o1, Employee o2) {
if(o1.getEno().compareTo(o2.getEno())!=0) {
return o1.getEno().compareTo(o2.getEno());
}else {
return -o1.getEname().compareTo(o2.getEname());
}
}
});
System.out.println(Arrays.toString(e));
}
}
class Employee {
private String eno;
private String ename;
private String dept;
public String getEno() {
return eno;
}
public void setEno(String eno) {
this.eno = eno;
}
public String getEname() {
return ename;
}
public void setEname(String ename) {
this.ename = ename;
}
public String getDept() {
return dept;
}
public void setDept(String dept) {
this.dept = dept;
}
public Employee(String eno, String ename, String dept) {
super();
this.eno = eno;
this.ename = ename;
this.dept = dept;
}
public Employee() {
super();
}
@Override
public String toString() {
return "Employee [eno=" + eno + ", ename=" + ename + ", dept=" + dept + "]";
}
}
java常用类——比较器的更多相关文章
- java常用类 比较器/system/math/big
		
Java 比较器 自然排序:java.lang.Comparable 定制排序:java.util.Comparator 自然排序:java.lang.Comparable Comparable接口 ...
 - Java基础 —— Java常用类
		
Java常用类: java.lang包: java.lang.Object类: hashcode()方法:返回一段整型的哈希码,代表地址. toString()方法:返回父类名+"@&quo ...
 - Java常用类学习笔记总结
		
Java常用类 java.lang.String类的使用 1.概述 String:字符串,使用一对""引起来表示. 1.String声明为final的,不可被继承 2.String ...
 - Java 常用类总结(SE基础)
		
本篇博客对java常用类相关知识进行了归纳总结,比较详细,适用于学习和复习. 1. 字符串相关的类 1.1 String String是一个final类,代表不可变的字符序列.不可被继承. Strin ...
 - Java常用类的使用
		
Java常用类 1. Optional 在我们的开发中,NullPointerException可谓是随时随处可见,为了避免空指针异常,我们常常需要进行 一 些防御式的检查,所以在代码中常常可见if( ...
 - Java常用类之要点总结
		
Java常用类之要点总结
 - Java常用类:包装类,String,日期类,Math,File,枚举类
		
Java常用类:包装类,String,日期类,Math,File,枚举类
 - Java常用类笔记(学习尚硅谷java基础教程)
		
一.Java根类Object类1.toString()方法 1)以文本对象返回,故toString()的定义为public String toString() {} 2)默认的字符串输出是:包.类名@ ...
 - Java常用类之String类、Stringbuffer和Random类练习
		
定义一个StringBuffer类对象, 1)使用append方法向对象中添加26个字母,并倒序遍历输入 2)删除前五个字符 package 第十一章常用类; /** * 定义一个StringBuff ...
 
随机推荐
- Spark使用Java读取mysql数据和保存数据到mysql
			
原文引自:http://blog.csdn.net/fengzhimohan/article/details/78471952 项目应用需要利用Spark读取mysql数据进行数据分析,然后将分析结果 ...
 - 将arcEngine9.3和dev9.2.4开发的项目升级成arcObject10.2和dev15.1.3过程中遇到的问题和解决
			
好久没碰.net了,arcgis更是感觉都忘干净了,今天将arcEngine9.3和dev9.2.4开发的一个项目升级成arcObject10.2和dev15.1.3过程中遇到了一系问题,留个笔记,留 ...
 - 2018-2-13-win10-uwp-改变鼠标
			
title author date CreateTime categories win10 uwp 改变鼠标 lindexi 2018-2-13 17:23:3 +0800 2018-2-13 17: ...
 - shell变量替换扩展 变量测试
 - tcp - 传输控制协议 (TCP)
			
总缆 SYNOPSIS #include <sys/socket.h> #include <netinet/in.h> tcp_socket = socket(PF_INET, ...
 - teb教程7
			
融合自定义的障碍物 简介:本部分讲解怎样考虑其他节点发布的多边形的障碍物. 1.在一些应用当中,可能不想依赖于代价地图或者想添加其他的除了点状的障碍物.你可以发送你自己的障碍物列表到teb_local ...
 - https原理 就是两次http
			
客户端在使用HTTPS方式与Web服务器通信时有以下几个步骤: (1)客户使用https的URL访问Web服务器,要求与Web服务器建立SSL连接. (2)Web服务器收到客户端请求后,会将网站的证书 ...
 - k8s-1.16 二进制安装
			
环境机器配置: 172.16.153.70 master 172.16.77.121 node1 172.16.77.122 node2 系统初始化 [root@iZbp1c31t0jo4w553hd ...
 - 关于计算机学习的书(doc,mobi,epub,pdf四种格式)
			
关于计算机学习的书(doc,mobi,epub,pdf四种格式) <html> <body> <div> 21天学通C+ +2016/6/22 18:47文條 30 ...
 - 计算机网络之IP地址与MAC地址
			
IP地址 IP地址(Internet Protocol Address): 缩写为IP Adress,是一种在Internet上的给主机统一编址的地址格式,也称为网络协议(IP协议)地址. 它为互联网 ...