zoukankan      html  css  js  c++  java
  • 集合框架学习之排序Comparable&Comoarator

    1、内置引用数据类型比较(常用)

    1.1  Comparable

    1、整数、小数Integer Float Double 直接比较基本数据类型的大小

    2、字符:比较的Unicode码只差

    3、字符串:

    1)如果其中一个是另外一个其实开始的子传,返回长度子差

    2)否则返回第一个不相等的Unicode码之差

    4java.util.Date:根据日期的长整形数比较

     

    1

     

     

     1 /**
     2  * 引用数据类型的排序
     3  * @author qjc
     4  *
     5  * 2016-3-10
     6  */
     7 public class ComparableDemo {
     8     /**
     9      * 数组排序(使用泛型方法)
    10      * @param arr
    11      */
    12     public static <T extends Comparable<T>> void sort(T[] arr){
    13         boolean sortede = true; //有序标示则不用比较
    14         for (int i = 0; i < arr.length-1; i++) {
    15             for (int j = 0; j < arr.length-1-i; j++) {
    16                 sortede = true;
    17                 if(((Comparable)arr[j]).compareTo(arr[j+1]) > 0){
    18                     T temp = arr[j];
    19                     arr[j] = arr[j+1];
    20                     arr[j+1] = temp;
    21                     sortede = false;
    22                 }
    23                 if(sortede){ //减少趟数
    24                     break;
    25                 }
    26             }
    27         }
    28     }
    29     public static void main(String[] args) {
    30         String[] arr = {"abc","ab","a"};
    31         sort(arr);
    32         for(String s : arr){
    33             System.out.println(s);
    34         }
    35         //结果: a ab abc
    36     }
    37 }

    1.2  Comparator

    提供排序的比较器,业务比较器

    实现java.util.Comparator接口

    重写public intcompare(T o1,T o2)

    作用:

    解耦:独立于实体类

    方便:便于应用各种排序规则

     

    2

     

     1 /**
     2  * 排序规则的业务类
     3  * @author qjc
     4  *
     5  * 2016-3-10
     6  */
     7 public class StringComp implements java.util.Comparator {
     8     /**
     9      * 按长度比较大小
    10       *     正数: >0
    11       *     负数: <0
    12       *     0   :==
    13      */
    14     @Override
    15     public int compare(Object o1, Object o2) {
    16         int len1 = ((String) o1).length();
    17         int len2 = ((String) o2).length();
    18         return len1 - len2;
    19     }
    20 }
    21  
    22 /**
    23  * Comparator排序
    24  * @author qjc
    25  *
    26  * 2016-3-10
    27  */
    28 public class ComparatorDemo {
    29     /**
    30      * 数组的排序(升序)+Comparator接口
    31      * @param arr
    32      * @param comm
    33      */
    34     public static <T> void sort(Object[] arr,Comparator<T> comm){
    35         boolean sorted = true;
    36         for (int i = 0; i < arr.length-1; i++) {
    37             for (int j = 0; j < arr.length-1-i; j++) {
    38                 if(comm.compare((T)arr[j], (T)arr[j+1]) > 0){
    39                     Object temp = arr[j];
    40                     arr[j] = arr[j+1];
    41                     arr[j+1] = temp;
    42                     sorted = false;
    43                 }
    44                 if(sorted){
    45                     break;
    46                 }
    47             }
    48         }
    49     }
    50     @Test
    51     public void testSort(){
    52         String[] arr = {"dss","fdss","fefeef"};
    53         sort(arr, new StringComp());
    54         System.out.println(Arrays.toString(arr));
    55         //输出结果: [dss, fdss, fefeef]
    56     }
    57 }

    1.3 Collections之排序

    Collections工具类,此类完全由在collection 上进行操作或返回 collection 的静态方法组成。

    提供了大量便于处理容器的方法

    关于排序:

    1public static <T extends Comparable<?super T>> void sort(List<T> list)

    2public static<T> void sort(List<T> list,Comparator<? super T> c)

     

    2、引用类型(自定义)

    2.1  Comparable

     

    按业务规则排序:

    1、实体类:java.lang.Comparable + compareTo

    3

    新闻信息排序:按时间(第一排序)、点击量(第二排序)、标题(第三排序)


     

    /**
     * 新闻条目实体类
     * @author qjc
     *
     * 2016-3-10
     */
    public class NewItem implements java.lang.Comparable<NewItem>{
        //标题
        private String title;
        //点击量
        private int hits;
        //时间
        private Date pubTime;
        //时间降序(第一排序) + 点击量升序(第二排序) + 标题降序
        @Override
        public int compareTo(NewItem ntm) {
            int result = 0;
            //比较时间
            result = - this.pubTime.compareTo(ntm.pubTime); //降序
            if(0 == result){
                //点击量
                result = this.hits - ntm.hits; //升序
                //点击量相同
                if(0 == result){
                    //标题
                    result = - this.title.compareTo(ntm.title); //降序
                }
            }
            return result;
        }
        @Override
        public String toString() {
            StringBuilder sb = new StringBuilder();
            sb.append("标题:").append(this.title);
            sb.append("时间:").append(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(this.pubTime));
            sb.append("点击量:").append(this.hits).append("
    ");
            return sb.toString();
        }
        //getter and setter...
    }
     
    /**
     * 
     * @author qjc
     *
     * 2016-3-10
     */
    public class NewItemApp {
     
        @Test
        public void test(){
            List<NewItem> news = new ArrayList<>();
            news.add(new NewItem("袁贵仁:十三五期间9年义务教育不会延长",100,
                    new Date(System.currentTimeMillis()-1000*60*60)));
            news.add(new NewItem("沪指收跌2.02%危及2800点 分析:三因素影响A股",999,
                    new Date()));
            news.add(new NewItem("女足回京球迷献吻 盼奥运进四强拿牌",888,
                    new Date(System.currentTimeMillis()+1000*60*60)));
            System.out.println("排序前:"+news);
            System.out.println("====================================");
            //Collections工具类排序(默认升序)
            Collections.sort(news);
            System.out.println("排序后:"+news);
        }
    }

     输出结果:

    排序前:

    [标题:袁贵仁:十三五期间9年义务教育不会延长时间:2016-03-10 21:33:28点击量:100

    ,标题:沪指收跌2.02%危及2800分析:三因素影响A股时间:2016-03-10 22:33:28点击量:999

    ,标题:女足回京球迷献吻盼奥运进四强拿牌时间:2016-03-1023:33:28点击量:888

    ]

    ====================================

    排序后:

    [标题:女足回京球迷献吻盼奥运进四强拿牌时间:2016-03-10 23:33:28点击量:888

    ,标题:沪指收跌2.02%危及2800分析:三因素影响A股时间:2016-03-10 22:33:28点击量:999

    ,标题:袁贵仁:十三五期间9年义务教育不会延长时间:2016-03-1021:33:28点击量:100

    ]

     

    2.2  Comparator

    2、业务排序类:java.util.Comparator + compare

    优点:

    • 解耦:与实体类分类
    • 方便:应对多变排序规则

     

    4

    按商品价格排序

     1 /**
     2  * 商品类
     3  * @author qjc
     4  *
     5  * 2016-3-10
     6  */
     7 public class Goods {
     8     //商品名
     9     private String name;
    10     //收藏量
    11     private int fav; 
    12     //价格
    13     private double price;
    14     @Override
    15     public String toString() {
    16         return "商品名:"+this.name+",收藏量"+this.fav+",价格"+this.price+"
    ";
    17     }
    18     //getter and setter...
    19 }
    20  
    21 /**
    22  * 按价格排序的业务类(降序)
    23  * @author qjc
    24  *
    25  * 2016-3-10
    26  */
    27 public class GoodsPriceComp implements java.util.Comparator<Goods>{
    28  
    29     @Override
    30     public int compare(Goods o1, Goods o2) {
    31         return -(o1.getPrice()-o2.getPrice()>0 ? 1 : (o1.getPrice()==o2.getPrice())?0 : -1);
    32     }
    33 }
    34  
    35 /**
    36  * 
    37  * @author qjc
    38  *
    39  * 2016-3-10
    40  */
    41 public class GoodsApp {
    42     @Test
    43     public void test(){
    44         List<Goods> list = new ArrayList<>();
    45         list.add(new Goods("iphone 5SE",1800,3888));
    46         list.add(new Goods("iphone 7",1998,5888));
    47         list.add(new Goods("Galaxy S7",2000,4888));
    48         System.out.println("排序前:"+list);
    49         //排序
    50         Collections.sort(list,new GoodsPriceComp());
    51         System.out.println("排序后:"+list);
    52     }
    53 }


    输出结果:

    排序前:

    [商品名:iphone 5SE,收藏量1800,价格3888.0

    ,商品名:iphone 7,收藏量1998,价格5888.0

    ,商品名:Galaxy S7,收藏量2000,价格4888.0

    ]

    排序后:

    [商品名:iphone 7,收藏量1998,价格5888.0

    ,商品名:Galaxy S7,收藏量2000,价格4888.0

    ,商品名:iphone 5SE,收藏量1800,价格3888.0

    ]


    3.3  TreeSet和TreeMap集合排序

     

    3.3.1 TreeSet:
        
    数据元素可以排序且不可以重复

    • 确保元素实体可以排序
    • 排序比较器

    publicTreeSet(Compartor<? super E> comparator)

     

    对比Set接口:HashSet,元素必须重写hashcodeequals方法。

    去重:比较等于0即重复

     

    例5:使用TreeSet无参构造实体类实现Comparable

     

    /**
     * 实体类实现Comparable
     * @author qjc
     *
     * 2016-3-11
     */
    public class Worker implements java.lang.Comparable<Worker>{
        //工种
        private String type;
        //工资
        private double salary;
        //按工资升序
        @Override
        public int compareTo(Worker o) {
            return this.salary>o.salary?1:this.salary==o.salary?0:-1;
        }
        //getter and setter..
    }
     
    /**
     * 使用Comparable排序
     * @author qjc
     *
     * 2016-3-11
     */
    public class TreeSetDemo2 {
        public static void main(String[] args) {
            Worker w1 = new Worker("教师",12000);
            Worker w2 = new Worker("公务员",8000);
            Worker w3 = new Worker("程序猿",6000);
            TreeSet<Worker> employeess = new TreeSet<>();
            employeess.add(w1);
            employeess.add(w2);
            employeess.add(w3);
            System.out.println(employeess);
        }
    }

    例6:使用TreeSet带参构造使用Comparator比较器

     

     1 public class Person {
     2     private String name;
     3     //帅气指数
     4     private int handsome;
     5     //geter and setter..
     6 }
     7  
     8 /**
     9  * 提供解耦方式排序
    10  * @author qjc
    11  *
    12  * 2016-3-11
    13  */
    14 public class TreeSetDemo {
    15     public static void main(String[] args) {
    16         Person p1 = new Person("刘德华", 2000);
    17         Person p2 = new Person("梁朝伟", 2200);
    18         Person p3 = new Person("鹿晗", 1500);
    19         //依次放到TreeSet容器中,使用排序的业务类(内部类)
    20         TreeSet<Person> persons = new TreeSet<>(
    21                 new java.util.Comparator<Person>(){
    22                     @Override
    23                     public int compare(Person o1, Person o2) {
    24                         //降序
    25                         return -(o1.getHandsome() - o2.getHandsome());
    26                     }
    27                 }
    28                 );
    29         //TreeSet 在添加数据时排序
    30         persons.add(p1);
    31         persons.add(p2);
    32         persons.add(p3);
    33         System.err.println(persons);
    34     }
    35 }
    36  

     

    注意:

    在添加数据时排序,数据更改不会影响原来的顺序,不要修改数据,否则可能重复。 ---可以使用final修饰

     

     

    3.3.2 TreeMap:

    • 确保key可以排序
    • 提供比较器

    publicTreeMap(Comparator<? super K> comparator)

     

    例:与TreeSet同理


    总结:

     

    相同点:

    ComparableComparator都是用来实现集合、数组中元素的比较、排序的

    不同点:

    1Comparable是在集合内部定义的方法实现的排序,而Comparator是在集合外部实现的排序,

    所以,如想实现排序,就需要在集合外定义 Comparator接口的方法或在集合内实现 Comparable接口的方法。

    Comparator位于包java.util下,而Comparable位于包java.lang

    2Comparable是一个对象,本身就已经支持自比较所需要实现的接口(如IntegerStringFloatDoubleDate底层都实现了Comparable接口 自己就可以完成比较大小操作)

    自定义的类要在加入list容器中后能够排序,可以实现Comparable接口,在用Collections类的sort方法排序时,如果不指定Comparator,那么就以自然顺序排序,这里的自然顺序就是实现Comparable接口设定的排序方式,并且是升序。

    3Comparator是一个专用的比较器,当这个对象不支持自比较或者自比较函数不能满足你的要求时,你可以写一个比较器来完成两个对象之间大小的比较。

    Comparator 与实体类分类于系统解耦优点,比如说例4按商品排序,如果需要按名称排序(或改升序、降序),只需要在业务类修改,在应变多变规则时方便程序修改和维护。所以推荐使用Comparator



  • 相关阅读:
    (原创)智能电能表SM1算法开发套件(主站接口) 基础资料篇
    ora12500 tns 监听程序无法启动专用服务器进程
    老微开放下载地址了,Microsoft Visual Studio 2010 旗舰版试用版
    如何实现一套鼠标键盘控制二台主机
    (原创)智能电能表SM1算法开发套件(主站接口) 开发篇
    Win8消费者预览版各语言版本下载地址
    50个必备的实用jQuery代码段 DWZ富客户端
    DWZ富客户端框架设计思路与学习建议 DWZ富客户端
    Mysql嵌套集合模型【省份城市示例】 DWZ富客户端
    DWZRIA v1.3 RC1 发布 DWZ富客户端
  • 原文地址:https://www.cnblogs.com/dooor/p/5285486.html
Copyright © 2011-2022 走看看