原文地址https://segmentfault.com/a/1190000005738975

实体类:java.lang.Comparable(接口) + comareTo(重写方法),业务排序类 java.util.Comparator(接口) + compare(重写方法).

这两个接口我们非常的熟悉,但是 在用的时候会有一些不知道怎么下手的感觉,现在用案例进行总结,消除对这个知识点的理解盲区(个人的理解,如果有错误 请多多指教)。
一,在实际的需求中,我们需要根据对象的各种属性(标题,时间,点击率,销售额...)进行排序(升序,降序),可以在数据库的sql上进行处理,但是 不是每一个场景 都适合在sql上进行处理,我们有时候需要在程序根据不同的属性,对一个对象进行各种排序 通过页面呈现给用户。
下面有这样的一个需求,一种商品(商品名,销售量,生产日期),根据生产日期降序 销售量升序 商品名称降序

思路:首先按照日期降序,如果日期相同 按照销售量升序,如果销售量相同,按周商品的名称降序
1,创建需要比较的对象的java bean
创建 Bean的快捷键:
1),带参数的构造器:// Shift + Alt + S -->O
2),不带参数的构造器: //Alt + / 生成空的构造方法
3),生成 get set方法:// Shift + Alt + S --> R + Table + Enter + Shift +Table -->Enter

/**
* 商品po类
*/
public class Items implements java.lang.Comparable<Items> {
private String title;
private int hits;
private Date pubTime;
public Items() {}
public Items(String title, int hits, Date pubTime) {
super();
this.title = title;
this.hits = hits;
this.pubTime = pubTime;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public int getHits() {
return hits;
}
public void setHits(int hits) {
this.hits = hits;
}
public Date getPubTime() {
return pubTime;
}
public void setPubTime(Date pubTime) {
this.pubTime = pubTime;
}
//时间降序 点击量升序 标题降序
@Override
public int compareTo(Items o) {
int result = 0;
//按照生产时间降序
result = - this.pubTime.compareTo(o.pubTime);
if(0==result){//如果生产时间相同 就按照销售量升序排列
result = this.hits-o.hits;
if(0==result){//如果销售量相同 按照名字降序排列
result = - this.title.compareTo(o.title);
}
}
return result;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("商品名称").append(this.title);
sb.append("销售量").append(this.hits);
sb.append("生产时间").append(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(this.pubTime)).append("\n");
return sb.toString();
}
}

2,造数据,比较

    //时间降序, 销售量升序, 标题降序
public static void main(String[] args) {
List<Items> item
= new ArrayList<Items>();
item.add(new Items("abcitems"
,30,new Date(System.currentTimeMillis()-1000*60*60)));
item.add(new Items("abcfgitems"
,30,new Date(System.currentTimeMillis()-1000*60*50)));
item.add(new Items("abcditems"
,100,new Date()));
item.add(new Items("abefNews"
,50,new Date(System.currentTimeMillis()-1000*60*60)));
System.out.println("----------排序前----------");
System.out.println(item);
System.out.println("----------排序后----------");
Collections.sort(item);
System.out.println(item);
}

二,Comparator的应用场景
一般比较字符串是按照unicode的大小进行排序的,但是我需要按照字符串的长度进行排序,下面是实现的案例:
首先,定义比较的业务规则

/**
* 定义业务的比较规则,我需要按照字符串的长度进行比较(在实际的场景中,可以根据业务的需求,灵活的改变比较规则,实现排序)
*/
public class CompareString implements java.util.Comparator<String> {
@Override
public int compare(String o1, String o2) {
int len1 = o1.length();
int len2 = o2.length();
return -(len1-len2);//需要按照降序排列
}
}

比较 字符串的长度,按照 降序排列

    public static void main(String[] args) {
List<String> list
= new ArrayList<String>();
list.add("abc");
list.add("abcd");
list.add("ab");
list.add("abd");
Collections.sort(list,new CompareString());
System.out.println(list);
//[abcd, abc, abd, ab]
}

比如 商品,我需要按照价格的降序排列,代码如下:
商品 po类

/**
* 商品po类
*/
public class Products {
private String title;
private int price;
public Products() {}
public Products(String title, int price) {
super();
this.title = title;
this.price = price;
} public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
@Override
public String toString() {
return "title=" + title+",price=" + price +"\n";
}
}

定义比较规则:

/**
* 按照价格的降序排列
*/
public class ProductCompare implements java.util.Comparator<Products> {
@Override
public int compare(Products o1, Products o2) {
return -( o1.getPrice()-o2.getPrice()>0?1: (o1.getPrice()==o2.getPrice()?0:-1));
}
}

数据比较:

public static void main(String[] args) {
List<Products> product
= new ArrayList<Products>();
product.add(new Products("a",120));
product.add(new Products("b",143432));
product.add(new Products("c",1892));
product.add(new Products("d",11092));
Collections.sort(product,new ProductCompare());
System.out.println(product);
结果:
[title=b,price=143432
title=d,price=11092
title=c,price=1892
title=a,price=120
] }

java实现Comparable接口和Comparator接口,并重写compareTo方法和compare方法的更多相关文章

  1. Java重写equals方法和hashCode方法

    package com.ddy; public class User {     private Integer id;     private String name;     private St ...

  2. Java基础知识强化84:System类之exit()方法和currentTimeMillis()方法

    1. exit方法: public static void exit(int status): 终止当前正在运行的Java虚拟机.参数用作状态码:根据惯例,非0的状态码表示异常终止. 调用System ...

  3. Java 重写hashCode 方法和equals方法

    package Container; import java.util.HashSet; import java.util.Iterator; /* Set 元素是无序的(存入和取出的顺序不一定一致) ...

  4. JAVA正确地自定义比较对象---如何重写equals方法和hashCode方法

    在实际应用中经常会比较两个对象是否相等,比如下面的Address类,它有两个属性:String province 和 String city. public class Address { priva ...

  5. java数组、java.lang.String、java.util.Arrays、java.lang.Object的toString()方法和equals()方法详解

    public class Test { public static void main(String[] args) { int[] a = {1, 2, 4, 6}; int[] b = a; in ...

  6. java中equals方法和hashcode方法的区别和联系,以及为什么要重写这两个方法,不重写会怎样

    一.在Object类中的定义为:public native int hashCode();是一个本地方法,返回的对象的地址值.但是,同样的思路,在String等封装类中对此方法进行了重写.方法调用得到 ...

  7. Object、String、数组的 toString() 方法和 equals() 方法及java.util.Arrays

    public class Test { public static void main(String[] args) { int[] a = {1, 2, 4, 6}; int[] b = a; in ...

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

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

  9. Java:实现对象的比较 comparable接口和comparator接口

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

随机推荐

  1. 【linux系列】配置免密登陆

    一.SSH无密码登录原理 此操作是为了搭建hadoop集群进行的操作 Master(NameNode|JobTracker)作为客户端,要实现无密码公钥认证,连接到服务器Salve(DataNode| ...

  2. MFC onpaint() ondraw()

    OnPaint是WM_PAINT消息的消息处理函数,在OnPaint中调用OnDraw,一般来说,用户自己的绘图代码应放在OnDraw中. OnPaint()是CWnd的类成员,负责响应WM_PAIN ...

  3. Android adb录制视频和截屏的dos脚本

    以下是本人写的脚本,用于录制android手机视频.截屏 dos脚本文件名:screenrecord.bat @ECHO OFF CLS color 0a set SCREEN_RECORD_SAVE ...

  4. Android studio Unable to start the daemon process

    Unable to start the daemon process.This problem might be caused by incorrect configuration of the da ...

  5. VScode首选项

    首选项相关的设置: // 将设置放入此文件中以覆盖默认设置 { "workbench.iconTheme": "vscode-icons", "wor ...

  6. stopImmediatePropagation和stopPropagation (事件、防止侦听)

    参考: ActionScript 3.0 Step By Step系列(六):学对象事件模型,从点击按扭开始 actionscript宝典 一.事件模型 egret中的事件模型和flash是一样的,但 ...

  7. IntelliJ IDEA导出Java 可执行Jar包

    extends:http://blog.sina.com.cn/s/blog_3fe961ae0102uy42.html 保证自己的Java代码是没有问题的,在IDEA里面是可以正常运行的,然后,按下 ...

  8. easyui---基础组件:panel

    加载easyui有两种方式:1种是html方式加载,1种是js加载. 要加载内容非常多时,用js,如果加载的东西比较少,用html就可以了. panel组件:面板 就是头 身展示 ,一个滚动条,几个关 ...

  9. Nginx防止恶意域名解析

    为了防止别人恶意将大量域名解析到自己的网站上面.我们可以对nginx做防止恶意域名解析,这样就只能通过自己的域名访问网站,其他域名就会显示错误500 打开Nginx配置文件nginx.conf,在原来 ...

  10. CH0101 a^b & CH0102 64位整数乘法

    大数取模的两道题. 虐狗宝典学习笔记: 两个数值执行算术运算时,以参与运算的最高数值类型为基准,与保存结果的变量类型无关.两个32位整数的成绩可能超过int类型的表示范围,但是CPU只会用一个32位寄 ...