文档章节

Java基础-对象排序详解

陶邦仁
 陶邦仁
发布于 2012/11/24 10:04
字数 1171
阅读 403
收藏 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));   
        } 
    } 
}



© 著作权归作者所有

共有 人打赏支持
陶邦仁
粉丝 1611
博文 420
码字总数 1483887
作品 0
海淀
技术主管
大数据开发培训:0基础学习Java编程语言有哪些知识点?

Java 技术通用、高效、具有平台移植性和安全性,广泛应用于PC、数据中心、游戏控制台、科学超级计算机、移动电话和互联网等,学习Java首先要知道学习知识点有哪些。在这就用加米谷大数据培训...

加米谷大数据
07/25
0
0
【目录导航】JAVA零基础进阶之路

【JAVA零基础入门系列】(已完结)导航目录 Day1 开发环境搭建 Day2 Java集成开发环境IDEA Day3 Java基本数据类型 Day4 变量与常量 Day5 Java中的运算符 Day6 Java字符串 Day7 Java输入与输出...

MFrank
06/21
0
0
一份关于 Java、Kotlin 与 Android 的学习笔记

JavaKotlinAndroidLearn 这是一份关于 Java 、Kotlin 、Android 的学习笔记,既包含对基础知识点的介绍,也包含对一些重要知识点的源码解析,笔记的大纲如下所示: Java 重拾Java(0)-基础知...

叶应是叶
08/08
0
0
Android--面试中遇到的问题总结(三)

《Android 开发工程师面试指南 LearningNotes 》,作者是陶程,由梁观全贡献部分。大家可以去知乎关注这两位用心的少年。这份指南包含了大部分Android开发的基础、进阶知识,不仅可以帮助准备...

sealin
2017/02/22
0
0
java web开发中Filter使用Annotation配置 (转载)

为了在java中得到request和response对象,搜索到了 《如何在Java的普通类中获取Session以及request对象 》这篇日志,当写完Filter后,却忘了如何配置Filter,于是又搜索到 《Java Web开发中F...

hiqj
2014/03/20
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Swift-系统默认UICollectionViewController的基本用法

不用xib创建时,需要重写 override init(collectionViewLayout layout: UICollectionViewLayout){} 在调用时需传 UICollectionViewLayout值,不然就会报错 let layout = UICollectionViewFlow......

west_zll
28分钟前
3
0
Spring Boot 最核心的 3 个注解详解

最近面试一些 Java 开发者,他们其中有些在公司实际用过 Spring Boot, 有些是自己兴趣爱好在业余自己学习过。然而,当我问他们 Spring Boot 最核心的 3 个注解是什么,令我失望的是鲜有人能答...

Java技术栈
29分钟前
5
0
Sqoop 增量导入导出及Job操作示例

增量导入 递增列的增量导入append # 第一次导入[root@node222 ~]# /usr/local/sqoop-1.4.7/bin/sqoop import --connect jdbc:mysql://192.168.0.200:3306/sakila?useSSL=false --table ac......

PeakFang-BOK
35分钟前
3
0
Thread中断的理解

★中断的理解:1)中断可以理解为线程的一个标识位属性;2)表示一个运行中的线程是否被其他线程进行了中断操作 中断好比其他线程向该线程打了个招呼,其他线程通过调用该线程的interrupt()...

karma123
43分钟前
3
0
App store 侵权投诉

App Store Content Dispute 侵权投诉 https://www.apple.com/legal/internet-services/itunes/appstorenotices/#?lang=zh...

壹峰
今天
5
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部