文档章节

java object比较排序

rabbit_mom
 rabbit_mom
发布于 2017/08/31 17:46
字数 1345
阅读 14
收藏 0
点赞 0
评论 0

在项目开发中,我们经常要对一组数据排序,或者升序或者降序,在java中排序有多种方式,最土的方法就是自己写排序算法,比如冒泡排序,快速排序,二叉树排序等,但一般不要自己写,jdk已经为我们提供了很多的 排序算法,我们采用拿来主义就成了。

在java中,要给数据排序,有两种实现方式,分别实现两个接口:

一种是实现Comparable接口
另一种是实现Comparator接口
在JDK类库中,有一部分类实现了Comparable接口,如Integer Double和String等。 
Comparable接口有一个comparTo(Object o)方法,它返回整数类型。对于表达式x.compareTo(y),如果返回值为0,则表示x和y相等,如果返回值大于0,则表示x大于y,如果返回值小于0,则表示x小于y.

查看Comparable接口源码
public interface Comparable<T> {
    public int compareTo(T o);
}
举个例子:

给公司职员排序,按照工号排序,先定义一个职员类

编写Employee类实现Comparable接口

package hello;

import org.apache.commons.lang3.builder.CompareToBuilder;
import org.apache.commons.lang3.builder.ToStringBuilder;


public class Employee implements Comparable<Employee>{
    //id是根据进入公司的先后顺序编码的
    private int id;
    //姓名
    private String name;
    //职位
    private Position position;
    public Employee(int id, String name, Position position) {
        super();
        this.id = id;
        this.name = name;
        this.position = position;
    }
    //按照id号排序,也就是资历的深浅排序
    [@Override](https://my.oschina.net/u/1162528)
    public int compareTo(Employee o) {
        // TODO Auto-generated method stub
        return new CompareToBuilder().append(id, o.id).toComparison();
    }
    [@Override](https://my.oschina.net/u/1162528)
    public String toString(){
         return ToStringBuilder.reflectionToString(this);
    }
    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Position getPosition() {
        return position;
    }

    public void setPosition(Position position) {
        this.position = position;
    }

}
这是一个简单的javabean,描述的是一个员工的基本信息,其中id是员工编号,按照进入公司的先后顺序编码,position是岗位描述,表示是经理还是普通职员,这是一个枚举类型:
public enum Position {
  Boss, Manager,staff
}
职位有三个级别:

Boss(老板), Manager(经理), Staff(职员)

按id排序 Employee类的compareTo()方法,是Comparable接口必须要实现的方法,使用apach的工具类来实现,表明是按照id的自然序列排序的(升序)。一切准备完毕,我们看看如何排序:


package hello;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

public class HelloWord {

    public static void main(String[] args) {
        List<Employee> list = new ArrayList<Employee>(5);
        // 一个老板
        list.add(new Employee(1001, "张三", Position.Boss));
        // 两个经理
        list.add(new Employee(1006, "赵四", Position.Manager));
        list.add(new Employee(1003, "王五", Position.Manager));
        // 两个职员
        list.add(new Employee(10002, "李六", Position.staff));
        list.add(new Employee(1005, "马牛", Position.staff));
        // 按照id排序,也就是按照资历深浅排序
        Collections.sort(list);
        for (Employee e : list) {
            System.out.println(e);
        }
    }
}

【运行结果】:

hello.Employee@46244bb9[id=1001,name=张三,position=Boss]
hello.Employee@4b5d7792[id=1003,name=王五,position=Manager]
hello.Employee@3e0a765c[id=1005,name=马牛,position=staff]
hello.Employee@7fbb6976[id=1006,name=赵四,position=Manager]
hello.Employee@6909037d[id=10002,name=李六,position=staff]
是按照id升序排列的,结果正确。    

按职位排序 本着“领导为先”的理念,按职位从高到低排序,先是老板,然后是经理,最后是普通职员,Employee已经是一个稳定类,为了一个排序功能修改它,影响按照id排序,不是一个好办法。

Collections.sort()方法有一个重载方法sort(List<T> list, Comparator<? super T> c),有一个Comparator接口参数,我们实现这个接口:

//职位排序器
class PositionComparator implements Comparator<Employee>{
    @Override
    public int compare(Employee o1, Employee o2) {
        //按照职位降序排列
        return o1.getPosition().compareTo(o2.getPosition());
    }

创建了一个职位排序法,按职位高低排序,测试一下:

        Collections.sort(list, new PositionComparator());
        for (Employee e : list) {
            System.out.println(e);
        }

【运行结果】:

hello.Employee@46244bb9[id=1001,name=张三,position=Boss]
hello.Employee@4b5d7792[id=1003,name=王五,position=Manager]
hello.Employee@7fbb6976[id=1006,name=赵四,position=Manager]
hello.Employee@3e0a765c[id=1005,name=马牛,position=staff]
hello.Employee@6909037d[id=10002,name=李六,position=staff]

按照职位排序,结果正确。

按照职位从低到高排序 为了照顾员工,需要按职位由低到高排序

两个办法:

Collections.reverse(List<?> list)方法实现倒序排列 Collections.sort(List<?> list,Collections.reverseOrder(new PositionComparator())也可以 用这两个方法来测试:

        Collections.reverse(list);
        for (Employee e : list) {
            System.out.println(e);
        }

        System.out.println("----");
        Collections.sort(list,
                Collections.reverseOrder(new PositionComparator()));
        for (Employee e : list) {
            System.out.println(e);
        }

【运行结果】:

hello.Employee@6909037d[id=10002,name=李六,position=staff]
hello.Employee@3e0a765c[id=1005,name=马牛,position=staff]
hello.Employee@7fbb6976[id=1006,name=赵四,position=Manager]
hello.Employee@4b5d7792[id=1003,name=王五,position=Manager]
hello.Employee@46244bb9[id=1001,name=张三,position=Boss]
----
hello.Employee@6909037d[id=10002,name=李六,position=staff]
hello.Employee@3e0a765c[id=1005,name=马牛,position=staff]
hello.Employee@7fbb6976[id=1006,name=赵四,position=Manager]
hello.Employee@4b5d7792[id=1003,name=王五,position=Manager]
hello.Employee@46244bb9[id=1001,name=张三,position=Boss]

按照职位由地到高排序,结果正确

先按职位排序,职位 相同按id排序 在compareTo或compare方法中先判断职位是否相等,职位相等再根据工号排序

修改Employee类的compareTo()方法为

@Override
    public int compareTo(Employee o) {
        return new CompareToBuilder()
            .append(position, o.position)    //按照职位排序
            .append(o.id,id).toComparison(); //工号排序
    }

排序代码:

Collections.sort(list);
        for (Employee e : list) {
            System.out.println(e);
        }

【运行结果】:

hello.Employee@4d871a69[id=1001,name=张三,position=Boss]
hello.Employee@631803fb[id=1006,name=赵四,position=Manager]
hello.Employee@4b5d7792[id=1003,name=王五,position=Manager]
hello.Employee@655538e5[id=1005,name=马牛,position=staff]
hello.Employee@20e0b1d6[id=1002,name=李六,position=staff]

总结:

实现了Comparable接口类表明自身可比较,有了比较才能进行排序; Comparator接口是一个工具类接口,用作比较,与原类的逻辑没有关系;

本文转载自:http://www.cnblogs.com/xiaobijia/p/5606197.html

共有 人打赏支持
rabbit_mom
粉丝 2
博文 25
码字总数 12119
作品 0
程序员
第二章 一节spring-core之comparator深入解读

前言 本章节深入讲解spring的comparator,使用与细节,帮助大家在项目里面正确使用comparator。源码解读无法通过文字很详细的解释,诠释。需要读者多次阅读,深入理解,组织逻辑,大脑慢慢形成...

鸟菜啊 ⋅ 04/18 ⋅ 0

【Java并发专题】27篇文章详细总结Java并发基础知识

努力的意义,就是,在以后的日子里,放眼望去全是自己喜欢的人和事! github:https://github.com/CL0610/Java-concurrency,欢迎题issue和Pull request。所有的文档都是自己亲自码的,如果觉...

你听___ ⋅ 05/06 ⋅ 0

java面试必备之ThreadLocal

按照传统的经验,如果某个对象是非线程安全的,在多线程环境下对象的访问需要采用synchronized进行同步。但是模板类并未采用线程同步机制,因为线程同步会降低系统的并发性能,此外代码同步解...

编程老司机 ⋅ 05/16 ⋅ 0

Spark高级排序与TopN问题揭密

[TOC] 引入 前面进行过wordcount的单词统计例子,关键是,如何对统计的单词按照单词个数来进行排序? 如下: 下面的测试都需要引入maven的依赖 Spark二次排序 测试数据与说明 需要进行二次排...

xpleaf ⋅ 04/28 ⋅ 0

java集合入门和深入学习,看这篇就差不多了

集合框架: Java中的集合框架大类可分为Collection和Map;两者的区别: Collection是单列集合;Map是双列集合 Collection中只有Set系列要求元素唯一;Map中键需要唯一,值可以重复 Collecti...

sihailoveyan ⋅ 05/04 ⋅ 0

java编程语言知识要点学习java基础英语单词表

Java是一种可以撰写跨平台应用软件的面向对象的程序设计语言。Java 技术具有卓越的通用性、高效性、平台移植性和安全性,广泛应用于PC、数据中心、游戏控制台、科学超级计算机、移动电话和互...

Java小辰 ⋅ 05/19 ⋅ 0

深入理解 ThreadLocal (这些细节不应忽略)

前言 对于 ThreadLocal 的使用,并不难。但要深入理解 ThreadLocal 的实现方式,需要细细揣摩。写本文前,我在网上看了很多关于 ThreadLocal 的分析,但却感到遗憾,因为很多文章存在着一定误...

徐志毅 ⋅ 04/11 ⋅ 0

14、Java并发性和多线程-Java ThreadLocal

以下内容转自http://ifeve.com/java-theadlocal/: Java中的ThreadLocal类可以让你创建的变量只被同一个线程进行读和写操作。因此,尽管有两个线程同时执行一段相同的代码,而且这段代码又有...

easonjim ⋅ 2017/06/16 ⋅ 0

给Java字节码加上”翅膀“的JIT编译器

给Java字节码加上”翅膀“的JIT编译器 上面文章在介绍Java的内存模型的时候,提到过由于编译器的优化会导致重排序的问题,其中一个比较重要的点地方就是关于JIT编译器的功能。JIT的英文单词是...

九劫散仙 ⋅ 昨天 ⋅ 0

2018年Java编程学习面试最全知识点总结

Java是一种可以撰写跨平台应用软件的面向对象的程序设计语言。Java 技术具有卓越的通用性、高效性、平台移植性和安全性,广泛应用于PC、数据中心、游戏控制台、科学超级计算机、移动电话和互...

Java小辰 ⋅ 05/14 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

Android JNI 读写Bitmap的方法

Java层创建Bitmap,通过JNI将Bitmap传到C/C++进行处理 Java部分 public static native boolean greenBitmap(Bitmap bitmap); C/C++部分 JNIEXPORT jboolean JNICALL Java_com_test_Test_gree......

国仔饼 ⋅ 7分钟前 ⋅ 0

一次性让你懂async/await,解决回调地狱

什么是async? 欢迎留言讨论 async 函数是 Generator 函数的语法糖。使用 关键字 async 来表示,在函数内部使用 await 来表示异步。相较于 Generator,async 函数的改进在于下面四点: 内置执...

阿K1225 ⋅ 8分钟前 ⋅ 0

angular常用命令

.下载更新操作 1.利用npm下载angular的命令行工具AngularCLI: npm install -g @angular/cli 2.下载jquery: npm install --save jquery 3.更新npm: npm i -g npm 4.更新angular: ng update ......

消散了的诗意 ⋅ 10分钟前 ⋅ 0

window.print 页面打印

定义和用法 print() 方法用于打印当前窗口的内容。 语法 window.print(); window.print() 实际上,是浏览器打印功能菜单的一种程序调用。与点击打印功能菜单一样,不能精确分页,不能设置纸型...

初学者的优化 ⋅ 11分钟前 ⋅ 0

魔兽世界 7.0版本上 PVE装备全攻略

  T套 因为大家应该都会打穿副本的所以具体是哪个boss我就不说了。   T1: 所有套装都在【熔火之心】出   T2: 头原来是在【奥妮克希亚的巢穴】改到黑翼之巢的奈法利安了,腿是在【熔火之...

wangchen1999 ⋅ 11分钟前 ⋅ 0

java.math.BigDecimal使用小结

原文地址 java.math.BigDecimal使用小结 divide方法 使用BigDecimal.divide方法时一定要考虑: 除数是否为0 商是否是无限小数 正确的使用方式 判断除数是否为0,是0做另外的处理逻辑 调用除法...

666B ⋅ 14分钟前 ⋅ 0

关于qstring转char乱码问题。

if (OpenClipboard(NULL)) { HGLOBAL hgClip; EmptyClipboard(); QByteArray byay = FValue.toLocal8Bit(); //转latin编码 char *bochsrc_line = byay.data(); hgClip = GlobalAlloc(GMEM_DD......

backtrackx ⋅ 14分钟前 ⋅ 0

了解SSH加密和连接过程

介绍 SSH或安全shell是安全协议,也是安全管理远程服务器的最常用方式。通过使用多种加密技术,SSH提供了一种机制,用于在双方之间建立加密安全连接,对彼此进行身份验证,以及来回传递命令和...

吴伟祥 ⋅ 21分钟前 ⋅ 0

微信小程序

小程序的基础配置:导航栏和tabbar 在app.json文件中配置导航栏和tabrbar 导航栏的设置 设置导航,背景黑色,文字白色,文字内容 { "pages":[ "pages/index/index", "pages/logs/l...

上官清偌 ⋅ 24分钟前 ⋅ 0

【转】百度坐标坐标系之间的转换(JS版代码)

/** * Created by Wandergis on 2015/7/8. * 提供了百度坐标(BD09)、国测局坐标(火星坐标,GCJ02)、和WGS84坐标系之间的转换 *///定义一些常量var x_PI = 3.1415926535897932...

HAVENT ⋅ 25分钟前 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部