文档章节

Java基础-对象排序详解

陶邦仁
 陶邦仁
发布于 2012/11/24 10:04
字数 1171
阅读 439
收藏 5

阿里云携手百名商业领袖、技术大咖,带您一探行进中的数字新基建!>>>

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));   
        } 
    } 
}



© 著作权归作者所有

陶邦仁
粉丝 1715
博文 420
码字总数 1483963
作品 0
海淀
技术主管
私信 提问
加载中

评论(0)

Java程序员从笨鸟到菜鸟全部博客目录【2012年十一月七日更新】

本文来自:曹胜欢博客专栏。转载请注明出处:http://blog.csdn.net/csh624366188 大学上了一年半,接触java也一年半了,虽然中间也有其他东西的学习,但是还是以java为主路线,想想这一年半,...

长平狐
2012/11/12
174
0
Java程序员从笨鸟到菜鸟全部博客目录【2012年十一月七日更新】

本文来自:曹胜欢博客专栏。转载请注明出处:http://blog.csdn.net/csh624366188 大学上了一年半,接触java也一年半了,虽然中间也有其他东西的学习,但是还是以java为主路线,想想这一年半,...

长平狐
2012/11/12
280
0
《Java程序员由笨鸟到菜鸟》电子版书正式发布,欢迎大家下载

在众多朋友的支持和鼓励下,《Java程序员由菜鸟到笨鸟》电子版终于和大家见面了。本电子书涵盖了从java基础到javaweb开放框架的大部分内容。在编写的过程中,难免会出现一些错误,希望大家能...

长平狐
2012/11/12
359
0
《Java程序员由笨鸟到菜鸟》电子版书正式发布,欢迎大家下载

在众多朋友的支持和鼓励下,《Java程序员由菜鸟到笨鸟》电子版终于和大家见面了。本电子书涵盖了从java基础到javaweb开放框架的大部分内容。在编写的过程中,难免会出现一些错误,希望大家能...

长平狐
2012/11/12
185
0
《数据结构与算法系列》合集整理

《数据结构与算法系列》合集整理 整理来自博客园skywang12345,以下摘自作者介绍: “最近抽空整理了"数据结构和算法"的相关文章。在整理过程中,对于每种数据结构和算法分别给出"C"、"C++"...

kaixin_code
2018/12/01
303
0

没有更多内容

加载失败,请刷新页面

加载更多

(人才测评)桌面运维工程师的招聘入职测评方案

桌面运维工程师,作为IT技术支持岗位的一种,不仅要有扎实的技术基础,还要有较强的时间观念意识,同时还应具备较强的逻辑思维能力和人际沟通能力,这样才能称得上一名合格的桌面运维工程师。...

蛤蟆丸子
24分钟前
37
0
JavaFX初探(菜单)

JavaFX初探(菜单) 本节我们介绍如何创建菜单、菜单栏、增加菜单项、为菜单分类,创建子菜单、设置菜单上下文。你可以使用下面的类来创建菜单。 MenuBar MenuItem Menu CheckMenuItem Radi...

whoisliang
28分钟前
20
0
Springboot 系列(四)Spring Boot 日志框架

文章已经收录在 Github.com/niumoo/JavaNotes ,更有 Java 程序员所需要掌握的核心知识,欢迎Star和指教。 欢迎关注我的公众号,文章每周更新。、 注意:本 Spring Boot 系列文章基于 Spring...

未读代码
31分钟前
20
0
26. Go 语言中通道死锁经典错误案例详解

Hi,大家好,我是明哥。 在自己学习 Golang 的这段时间里,我写了详细的学习笔记放在我的个人微信公众号 《Go编程时光》,对于 Go 语言,我也算是个初学者,因此写的东西应该会比较适合刚接触...

王炳明
36分钟前
13
0
SpringBoot 整合 Redis 缓存

1.首先导入使用Maven导入jar包 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId></dependency><......

FH-Admin
今天
12
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部