文档章节

Java基础-对象排序详解

陶邦仁
 陶邦仁
发布于 2012/11/24 10:04
字数 1171
阅读 399
收藏 5
点赞 0
评论 0

1. Comparator,Comparable接口区别

comparable是通用的接口,用户可以实现它来完成自己特定的比较,而comparator可以看成一种算法的实现,当需要容器集合 collection需要比较功能的时,来指定这个比较器,这可以看出一种设计模式,将算法和数据分离,就像C++ STL中的函数对象一样。

Comparable应该比较固定,和一个具体类相绑定,而Comparator比较灵活,它可以被用于各个需要比较功能的类使用。可以说前者属于“静态绑定”,而后者可以“动态绑定”。

一个类实现了Camparable接口表明这个类的对象之间是可以相互比较的。如果用数学语言描述的话就是这个类的对象组成的集合中存在一个全序。这样,这个类对象组成的集合就可以使用Sort方法排序了。

而Comparator的作用有两个:
1. 如果类的设计师没有考虑到Compare的问题而没有实现Comparable接口,可以通过Comparator来实现比较算法进行排序。
2. 为了使用不同的排序标准做准备,比如:升序、降序或其他什么序。

2. Arrays和Collections类区别

要知道两个类:java.util.Arrays和java.util.Collections(注意和Collection的区别),Collection是集合框架的顶层接口,而Collections是包含了许多静态方法。我们使用Arrays对数组进行排序,使用Collections对集合框架容器进行排序,如ArraysList,LinkedList等。

对数组进行排序

对基本数据类型(primitive type)或String类型的数组进行排序:

int[] intArray = new int[] {4, 1, 3, -23}; 
Arrays.sort(intArray); 
// [-23, 1, 3, 4] 
String[] strArray = new String[] {"z", "a", "C"}; 
Arrays.sort(strArray); 
// [C, a, z] 
// Case-insensitive sort 
Arrays.sort(strArray, String.CASE_INSENSITIVE_ORDER); 
// [a, C, z] 
// Reverse-order sort 
Arrays.sort(strArray, Collections.reverseOrder()); 
// [z, a, C] 
// Case-insensitive reverse-order sort 
Arrays.sort(strArray, String.CASE_INSENSITIVE_ORDER); 
Collections.reverse(Arrays.asList(strArray)); 
// [z, C, a]

当然我们也可以指定数组的某一段进行排序比如我们要对数组下表0-2的部分(假设数组长度大于3)进行排序,其他部分保持不变,我们可以使用:

Arrays.sort(strArray,0,2);

这样,我们只对前三个元素进行了排序,而不会影响到后面的部分。

对对象数组进行排序

这个数组的自然顺序是未知的,因此我们需要为该类实现Comparable接口。

Name类

public class Name implements Comparable<Name>{ 
       public String firstName, lastName; 
       public Name(String firstName,String lastName){ 
              this.firstName=firstName; 
              this.lastName=lastName; 
       } 
       public int compareTo(Name o) { //实现接口 
              int lastCmp=lastName.compareTo(o.lastName); 
              return (lastCmp!=0?lastCmp:firstName.compareTo(o.firstName)); 
       } 
       public String toString(){ //便于输出测试 
              return firstName+" "+lastName; 
       } 
}

这样,当我们对这个对象数组进行排序时,就会先比较lastName,然后比较firstName 然后得出两个对象的先后顺序,就像compareTo(Name o)里实现的那样。用程序进行测试:

NameSort类

import java.util.*; 
public class NameSort { 
        public static void main(String[] args) { 
               Name[] nameArray = new Name[]{ 
                       new Name("John", "Lennon"), 
                       new Name("Karl", "Marx"), 
                       new Name("Groucho", "Marx"), 
                       new Name("Oscar", "Grouch") 
                       }; 
              Arrays.sort(nameArray); 
              for(int i=0;i<nameArray.length;i++){ 
                       System.out.println(nameArray[i].toString()); 
              } 
        } 
}

对集合框架进行排序

如果已经理解了Arrays.sort()对数组进行排序的话,集合框架的使用也是大同小异。只是将Arrays替换成了Collections,注意Collections是一个类而Collection是一个接口。

假如有这样一个链表:

LinkedList list=new LinkedList(); 
list.add(4); 
list.add(34); 
list.add(22); 
list.add(2);

我们只需要使用:

Collections.sort(list);

就可以将list里的元素按从小到大的顺序进行排序,结果就成了: [2, 4, 22, 34]。

如果LinkedList里面的元素是String,同样会像基本数据类型一样从小到大排序。如果要实现反序排序也就是从大到小排序:

Collections.sort(list,Collectons.reverseOrder());

如果LinkedList里面的元素是自定义的对象,可以像上面的Name对象一样实现Comparable接口,就可以让Collection.sort()为您排序了。

对对象进行自定义排序

可以使用sort(List<T> list, Comparator<? super T> c)这个方法进行排序,FIRST_NAME_ORDER类。

import java.util.*; 
public class FIRST_NAME_ORDER implements Comparator<Name>{ 
          public int compare(Name n1, Name n2) { 
                  int firstCmp=n1.firstName.compareTo(n2.firstName); 
                  return (firstCmp!=0?firstCmp:n1.lastName.compareTo(n2.firstName)); 
          } 
}

在上面的NameSort中将 Arrays.sort(nameArray);替换成下面语句

List<Name> list=Arrays.asList(nameArray); // 将名字数组转化为List 
Collections.sort(list,new FIRST_NAME_ORDER());

下面举例根据TreeMap的key进行降序排序

import java.util.*; 
public class DescMap implements Comparator<String>{ 
    public int compare(String o1, String o2) {         
        int map1 = Integer.parseInt(o1);         
        int map2 = Integer.parseInt(o2);         
        return map2-map1; 
    } 
    public static void main(String[] args) {         
        String[] arraySources = {"1","2","3","0"};         
        int[] arrayValue = {1,424,32,123};         
        Map mapCurrentWebSite = new TreeMap(new DescMap());         
        
        for(int i=0;i<arraySources.length;i++) {               
            mapCurrentWebSite.put(arraySources[i],new Integer(arrayValue[i]));          
        }         
        
        Collection col = mapCurrentWebSite.values();         
        Vector v1 = new Vector(col);         
        
        for(int i=0;i<v1.size();i++) {
            System.out.println((Integer)v1.get(i));   
        } 
    } 
}



© 著作权归作者所有

共有 人打赏支持
陶邦仁
粉丝 1556
博文 388
码字总数 1483822
作品 0
海淀
技术主管
【Java并发专题】27篇文章详细总结Java并发基础知识

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

你听___ ⋅ 05/06 ⋅ 0

Java基础之反射(非常重要)

反射是框架设计的灵魂 (使用的前提条件:必须先得到代表的字节码的Class,Class类用于表示.class文件(字节码)) 一、反射的概述 JAVA反射机制是在运行状态中,对于任意一个类,都能够知道...

Java-老刘 ⋅ 05/15 ⋅ 0

Java序列化之Serializable

1.需求 1.什么是Java序列化 2.详解 1.序列化 理解为"打碎"即可 2.在书本上序列化的意思是将Java对象转为二进制 3.java平台允许我们在内存中创建对象,当JVM运行时对象才能存在,如果JVM停止,对...

村长大神 ⋅ 05/08 ⋅ 0

Jenkins 教程(一)实现自动化打包及邮件通知

个人不喜欢装腔作势一堆专业术语放上去,让大多数人看不懂来提升逼格(所谓的专家),所以我简单的介绍jenkins是干啥的。本文使用jenkins,就是让它把git仓库里的东西取出来,然后在jenkins容器...

FantJ ⋅ 05/26 ⋅ 0

【J2EE】之常用的接口和协议

前言 初接触J2EE,会遇到很多之前没有遇到过的术语,下面我们来简单地汇总一下这些接口和协议吧。 各大接口和协议详解 JDBC 1.定义:Java数据库连接 2.地位:用于Java应用程序连接数据库的标...

m18633778874 ⋅ 04/26 ⋅ 0

Java反序列化漏洞的原理分析

  *本文原创作者:Moonlightos,本文属FreeBuf原创奖励计划,未经许可禁止转载   世界上有三件事最难:      把别人的钱装进自己的口袋里   把自己的想法装进别人的脑袋里   让自...

FreeBuf ⋅ 05/04 ⋅ 0

《成神之路-基础篇》JVM——垃圾回收(已完结)

Java内存模型,Java内存管理,Java堆和栈,垃圾回收 本文是[《成神之路系列文章》][1]的第一篇,主要是关于JVM的一些介绍。 持续更新中 Java之美[从菜鸟到高手演变]之JVM内存管理及垃圾回收 ...

⋅ 05/05 ⋅ 0

Spark高级排序与TopN问题揭密

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

xpleaf ⋅ 04/28 ⋅ 0

13、Java并发性和多线程-Java Volatile关键字

以下内容转自http://tutorials.jenkov.com/java-concurrency/volatile.html(使用谷歌翻译): Java 关键字用于将Java变量标记为“存储在主存储器”中。更准确地说,这意味着,每个读取volat...

easonjim ⋅ 2017/06/16 ⋅ 0

大型互联网架构必备技术——性能调优专题

性能调优 深入内核,直击故障 ,拒绝蒙圈 性能优化如何理解 1、性能基准 2、什么是性能优化 3、衡量标准 JVM调优 1、Jvm虚拟机内存剖析 2、垃圾收集器 3、实战调优案例与解决方案 4、Jvm运行...

Java高级架构 ⋅ 04/15 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

RabbitMQ学习以及与Spring的集成(三)

本文介绍RabbitMQ与Spring的简单集成以及消息的发送和接收。 在RabbitMQ的Spring配置文件中,首先需要增加命名空间。 xmlns:rabbit="http://www.springframework.org/schema/rabbit" 其次是模...

onedotdot ⋅ 20分钟前 ⋅ 0

JAVA实现仿微信红包分配规则

最近过年发红包拜年成为一种新的潮流,作为程序猿对算法的好奇远远要大于对红包的好奇,这里介绍一种自己想到的一种随机红包分配策略,还请大家多多指教。 算法介绍 一、红包金额限制 对于微...

楠木楠 ⋅ 32分钟前 ⋅ 0

Python 数电表格格式化 xlutils xlwt xlrd的使用

需要安装 xlutils xlwt xlrd 格式化前 格式化后 代码 先copy读取的表格,然后按照一定的规则修改,将昵称中的学号提取出来替换昵称即可 from xlrd import open_workbookfrom xlutils.copy ...

阿豪boy ⋅ 今天 ⋅ 0

面试题:使用rand5()生成rand7()

前言 读研究生这3 年,思维与本科相比变化挺大的,这几年除了看论文、设计方案,更重要的是学会注重先思考、再实现,感觉更加成熟吧,不再像个小P孩,人年轻时总会心高气傲。有1 道面试题:给...

初雪之音 ⋅ 今天 ⋅ 0

Docker Toolbox Looks like something went wrong

Docker Toolbox 重新安装后提示错误:Looks like something went wrong in step ´Checking if machine default exists´ 控制面板-->程序与应用-->启用或关闭windows功能:找到Hyper-V,如果处......

随你疯 ⋅ 今天 ⋅ 0

Guacamole 远程桌面

本文将Apache的guacamole服务的部署和应用,http://guacamole.apache.org/doc/gug/ 该链接下有全部相关知识的英文文档,如果水平ok,可以去这里仔细查看。 一、简介 Apache Guacamole 是无客...

千里明月 ⋅ 今天 ⋅ 0

nagios 安装

Nagios简介:监控网络并排除网络故障的工具:nagios,Ntop,OpenVAS,OCS,OSSIM等开源监控工具。 可以实现对网络上的服务器进行全面的监控,包括服务(apache、mysql、ntp、ftp、disk、qmail和h...

寰宇01 ⋅ 今天 ⋅ 0

AngularDart注意事项

默认情况下创建Dart项目应出现以下列表: 有时会因为不知明的原因导致列表项缺失: 此时可以通过以下步骤解决: 1.创建项目涉及到的包:stagehand 2.执行pub global activate stagehand或pub...

scooplol ⋅ 今天 ⋅ 0

Java Web如何操作Cookie的添加修改和删除

创建Cookie对象 Cookie cookie = new Cookie("id", "1"); 修改Cookie值 cookie.setValue("2"); 设置Cookie有效期和删除Cookie cookie.setMaxAge(24*60*60); // Cookie有效时间 co......

二营长意大利炮 ⋅ 今天 ⋅ 0

【每天一个JQuery特效】淡入淡出显示或隐藏窗口

我是JQuery新手爱好者,有时间就练练代码,防止手生,争取每天一个JQuery练习,在这个博客记录下学习的笔记。 本特效主要采用fadeIn()和fadeOut()方法显示淡入淡出的显示效果显示或隐藏元...

Rhymo-Wu ⋅ 今天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部