在实际应用中,我们往往有需要比较两个自定义对象大小的地方。而这些自定义对象的比较,就不像简单的整型数据那么简单,它们往往包含有许多的属性,我们一般都是根据这些属性对自定义对象进行比较的。所以Java中要比较对象的大小或者要对对象的集合进行排序,需要通过比较这些对象的某些属性的大小来确定它们之间的大小关系。

一般,Java中通过接口实现两个对象的比较,比较常用就是Comparable接口和Comparator接口。首先类要实现接口,并且使用泛型规定要进行比较的对象所属的类,然后类实现了接口后,还需要实现接口定义的比较方法(compareTo方法或者compare方法),在这些方法中传入需要比较大小的另一个对象,通过选定的成员变量与之比较,如果大于则返回1,小于返回-1,相等返回0。

一、Comparable接口

1.什么是Comparable接口

此接口强行对实现它的每个类的对象进行整体排序。此排序被称为该类的自然排序 ,类的 compareTo方法被称为它的自然比较方法 。实现此接口的对象列表(和数组)可以通过 Collections.sort(和 Arrays.sort )进行自动排序。实现此接口的对象可以用作有序映射表中的键或有序集合中的元素,无需指定比较器。

2.实现什么方法

int compareTo(T o)

比较此对象与指定对象的顺序。如果该对象小于、等于或大于指定对象,则分别返回负整数、零或正整数。

参数: o - 要比较的对象。

返回:负整数、零或正整数,根据此对象是小于、等于还是大于指定对象。

抛出:ClassCastException - 如果指定对象的类型不允许它与此对象进行比较。

3.实例

package com.mxl.algorithlm;

import java.util.Date;
/**
* 因为要实现对ConsumInfo对象的排序,所以在ConsunInfo类中要实现Comparable接口,也就是要实现compareTo()方法
* 具体的比较参照:依次按照price、uid进行倒序排序
* @author breeze
*
*/
public class ConsumInfo implements Comparable<ConsumInfo> {
private int uid;
private String name;
private double price;
private Date datetime; public ConsumInfo() {
// TODO Auto-generated constructor stub
} public ConsumInfo(int uid,String name,double price,Date datetime){
this.uid = uid;
this.name = name;
this.price = price;
this.datetime = datetime; } public int getUid() {
return uid;
} public void setUid(int uid) {
this.uid = uid;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public double getPrice() {
return price;
} public void setPrice(double price) {
this.price = price;
} public Date getDatetime() {
return datetime;
} public void setDatetime(Date datetime) {
this.datetime = datetime;
} @Override
public String toString() {
return "ConsumInfo [uid=" + uid + ", name=" + name + ", price=" + price
+ ", datetime=" + datetime + "]";
}
/**
* 这里比较的是什么, Collections.sort方法实现的就是按照此比较的东西排列
* 顺序(从小到大):
* if(price < o.price){
return -1;
}
if(price > o.price){
return 1;
}
* 倒序(从大到小):
* if(price < o.price){
return 1;
}
if(price > o.price){
return -1;
}
*
*/
@Override
public int compareTo(ConsumInfo o) {
//首先比较price,如果price相同,则比较uid
if(price < o.price){
return -1;
}
if(price > o.price){
return 1;
} if(price == o.price){
if(uid < o.uid){
return -1;
}
if(uid > o.uid){
return 1;
}
}
return 0;
} } //测试类 package com.mxl.algorithlm; import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List; public class ConsumInfoTest { public static void main(String[] args) { ConsumInfo consumInfo1 = new ConsumInfo(100, "consumInfo1", 400.0,new Date());
ConsumInfo consumInfo2 = new ConsumInfo(200, "consumInfo1", 200.0,new Date());
ConsumInfo consumInfo3 = new ConsumInfo(300, "consumInfo1", 100.0,new Date());
ConsumInfo consumInfo4 = new ConsumInfo(400, "consumInfo1", 700.0,new Date());
ConsumInfo consumInfo5 = new ConsumInfo(500, "consumInfo1", 800.0,new Date());
ConsumInfo consumInfo6 = new ConsumInfo(600, "consumInfo1", 300.0,new Date());
ConsumInfo consumInfo7 = new ConsumInfo(700, "consumInfo1", 900.0,new Date());
ConsumInfo consumInfo8 = new ConsumInfo(800, "consumInfo1", 400.0,new Date()); List<ConsumInfo> list = new ArrayList<ConsumInfo>();
list.add(consumInfo1);
list.add(consumInfo2);
list.add(consumInfo3);
list.add(consumInfo4);
list.add(consumInfo5);
list.add(consumInfo6);
list.add(consumInfo7);
list.add(consumInfo8);
System.out.println("排序前:");
//排序前
for(ConsumInfo consumInfo : list ){
System.out.println(consumInfo);
} Collections.sort(list);//排序
System.out.println("排序后:");
//排序后
for(ConsumInfo consumInfo :list){
System.out.println(consumInfo);
}
}
}

二、Comparator接口

与上面的Comparable接口不同的是:

①、Comparator位于包java.util下,而Comparable位于包java.lang下。

②、Comparable接口将比较代码嵌入需要进行比较的类的自身代码中,而Comparator接口在一个独立的类中实现比较。

③、如果前期类的设计没有考虑到类的Compare问题而没有实现Comparable接口,后期可以通过Comparator接口来实现比较算法进行排序,并且为了使用不同的排序标准做准备,比如:升序、降序。

④、Comparable接口强制进行自然排序,而Comparator接口不强制进行自然排序,可以指定排序顺序。

使用实例:

package test;

import java.util.Comparator;
/**
* 具体的比较类(比较器),实现Comparator接口
* @author breeze
*
*/
public class ComparatorConsunInfo implements Comparator<ConsumInfo> {
/**
* 顺序(从小到大):
* if(price < o.price){
return -1;
}
if(price > o.price){
return 1;
}
* 倒序(从大到小):
* if(price < o.price){
return 1;
}
if(price > o.price){
return -1;
}
*/
@Override
public int compare(ConsumInfo o1, ConsumInfo o2) {
//首先比较price,如果price相同,则比较uid
if(o1.getPrice() > o2.getPrice()){
return 1;
} if(o1.getPrice() < o2.getPrice()){
return -1;
} if(o1.getPrice() == o2.getPrice()){
if(o1.getUid() > o2.getUid()){
return 1;
}
if(o1.getUid() < o2.getUid()){
return -1;
}
}
return 0;
} } /**
* 需要进行比较的类
* @author breeze
*
*/
public class ConsumInfo{
private int uid;
private String name;
private double price;
private Date datetime; public ConsumInfo() {
// TODO Auto-generated constructor stub
} public ConsumInfo(int uid,String name,double price,Date datetime){
this.uid = uid;
this.name = name;
this.price = price;
this.datetime = datetime; } public int getUid() {
return uid;
} public void setUid(int uid) {
this.uid = uid;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public double getPrice() {
return price;
} public void setPrice(double price) {
this.price = price;
} public Date getDatetime() {
return datetime;
} public void setDatetime(Date datetime) {
this.datetime = datetime;
} @Override
public String toString() {
return "ConsumInfo [uid=" + uid + ", name=" + name + ", price=" + price
+ ", datetime=" + datetime + "]";
} } //测试类
public class ConsumInfoTest { public static void main(String[] args) { ConsumInfo consumInfo1 = new ConsumInfo(100, "consumInfo1", 400.0,new Date());
ConsumInfo consumInfo2 = new ConsumInfo(200, "consumInfo1", 200.0,new Date());
ConsumInfo consumInfo3 = new ConsumInfo(300, "consumInfo1", 100.0,new Date());
ConsumInfo consumInfo4 = new ConsumInfo(400, "consumInfo1", 700.0,new Date());
ConsumInfo consumInfo5 = new ConsumInfo(500, "consumInfo1", 800.0,new Date());
ConsumInfo consumInfo6 = new ConsumInfo(600, "consumInfo1", 300.0,new Date());
ConsumInfo consumInfo7 = new ConsumInfo(700, "consumInfo1", 900.0,new Date());
ConsumInfo consumInfo8 = new ConsumInfo(800, "consumInfo1", 400.0,new Date()); List<ConsumInfo> list = new ArrayList<ConsumInfo>();
list.add(consumInfo1);
list.add(consumInfo2);
list.add(consumInfo3);
list.add(consumInfo4);
list.add(consumInfo5);
list.add(consumInfo6);
list.add(consumInfo7);
list.add(consumInfo8); System.out.println("排序前:");
//排序前
for(ConsumInfo consumInfo : list ){
System.out.println(consumInfo);
}
ComparatorConsunInfo comparatorConsunInfo = new ComparatorConsunInfo();//比较器
Collections.sort(list,comparatorConsunInfo);//排序
System.out.println("排序后:");
//排序后
for(ConsumInfo consumInfo :list){
System.out.println(consumInfo);
}
}
}

Java:实现对象的比较 comparable接口和comparator接口的更多相关文章

  1. Java中实现对象的比较:Comparable接口和Comparator接口

    在实际应用中,我们往往有需要比较两个自定义对象大小的地方.而这些自定义对象的比较,就不像简单的整型数据那么简单,它们往往包含有许多的属性,我们一般都是根据这些属性对自定义对象进行比较的.所以Java中 ...

  2. Java—集合框架 Collections.sort()、Comparable接口和Comparator接口

    Collentions工具类--java.util.Collections Collentions是Java集合框架中,用来操作集合对象的工具类,也是Java集合框架的成员,与List.Map和Set ...

  3. Java6.0中Comparable接口与Comparator接口详解

    Java6.0中Comparable接口与Comparator接口详解 说到现在,读者应该对Comparable接口有了大概的了解,但是为什么又要有一个Comparator接口呢?难道Java的开发者 ...

  4. java中Comparatable接口和Comparator接口的区别

    1.不同类型的排序规则 .自然排序是什么?   自然排序是一种升序排序.对于不同的数据类型,升序规则不一样:   BigDecimal BigInteger Byte Double Float Int ...

  5. Comparable接口与Comparator接口的比较————总结

    之前的两篇文章主要学习了Comparable接口和Comparator接口的学习.既然已经学习完了,现在就趁热打铁,进行总结吧! Comparable接口和Comparator接口的共同点: 1. 都 ...

  6. 比较器:Compare接口与Comparator接口区别与理解

    一.实现Compare接口与Comparator接口的类,都是为了对象实例数组排序的方便,因为可以直接调用 java.util.Arrays.sort(对象数组名称),可以自定义排序规则. 不同之处: ...

  7. Comparatable接口和Comparator接口的使用与区别

    这篇博文可以为你解决的问题如下: 什么是自然排序 Collections.sort()与Arrays.sort()的异同点 Comparatable接口和Comparator接口各自的排序依据(理论讲 ...

  8. Java中的Comparable接口和Comparator接口

    Comparator位于包java.util下,比较器,是在集合外部定义排序.Comparable位于包java.lang下,代表当前对象可比较的,是在集合内部实现排序. Comparable代表一个 ...

  9. Java之Comparable接口和Comparator接口

    Comparable & Comparator 都是用来实现集合中元素的比较.排序的: Comparable 是在集合内部定义的方法实现的排序: Comparator 是在集合外部实现的排序: ...

随机推荐

  1. iOS组件化方案的几种实现

    最近研究了一下项目的组件化,把casa.bang.limboy的有关组件化的博客看了一遍,学到了不少东西,对目前业界的组件化方案有了一定的了解.这些高质量的博客大致讨论了组件化的三种方案:url-bl ...

  2. msbuildtoolspath is not specified for the toolsversion xx

    本地先是安装的vs2015,由于项目需求又安装了vs2008,在用vs2008打开.csproj工程文件,出现了上图的错误. 这一般是由于安装了vs2015和vs2008冲突产生的问题. 解决方案: ...

  3. 第一次使用windows版的Git,附上一些配置和最常用的git命令

    Git配置:git config --global user.name "用户姓名" git config --global user.emall "用户邮箱" ...

  4. 教程:基于访问控制的ABAP CDS视图权限

    Hi! 对每一个CDS视图,我们都可以通过DCL(Data Control Language)定义访问控制.在这篇文章中,我会介绍ABAP CDS视图中非常重要的一面:权限管理. 本文的阐述基于我正在 ...

  5. [Linux] Desktop Management

    xrandr --output Virtual1 --mode 1360x768 Extend Display Size

  6. 跨server传输数据注意事项

    我们需要模拟客服端 首先导入相关的jar包 文件,Jersey的相关jar包 实现客服端的代码为: @Test    public  void testClient() {        //图片生成 ...

  7. Javascript是单线程的深入分析(转)

    http://www.cnblogs.com/Mainz/p/3552717.html

  8. Struts2使用小问题-NoSuchFieldException

    五月 12, 2017 4:55:14 下午 com.opensymphony.xwork2.util.logging.jdk.JdkLogger warn 警告: couldn't clear to ...

  9. # hadoop入门第六篇:Hive实例

    前言   前面已经讲了如何部署在hadoop集群上部署hive,现在我们就做一个很小的实例去熟悉HIVE QL.使用的数据是视频播放数据包括视频编码,播放设备编码,用户账号编码等,我们在这个数据基础上 ...

  10. Eclipse关闭项目

    Eclipse 关闭项目 为什么要关闭项目? Eclipse 工作空间包含了多个项目.一个项目可以是关闭或开启状态. 项目打开过多影响有: 消耗内存 占用编译时间:在删除项目.class 文件(Cle ...