• 一点一点看JDK源码(五)java.util.ArrayList 后篇之sort与Comparator


    一点一点看JDK源码(五)java.util.ArrayList 后篇之sort与Comparator

    liuyuhang原创,未经允许禁止转载

    本文举例使用的是JDK8的API

    目录:一点一点看JDK源码(〇)

    Comparator为额外实现的比较接口,与类本身无关

    该接口在ArrayList的sort中有应用(很多时候都可以用的,只是以此举例)

    Comparator接口主要用途有两种,

    1、比较有序集合内任意两个元素A、B(完全遍历的compareTo方法,于compare方法内实现)

      若A元素小于B元素,则返回1,donothing

      若A元素等于B元素,则返回0,donothing

      若A元素小于B元素,则返回-1,交换元素位置

      若compare方法的返回值遵循以上原则,则进行排序

      示例代码如下:

     1 package com.FM.ArrayListStudy;
     2 
     3 import java.util.ArrayList;
     4 import java.util.Comparator;
     5 
     6 public class ComparatorInArrayListStudy01 {
     7     public static void main(String[] args) {
     8         ArrayList<Integer> list = new ArrayList<Integer>();
     9         list.add(1);
    10         list.add(12);
    11         list.add(3);
    12         list.add(4);
    13         list.add(3);
    14         list.add(11);
    15         list.add(7);
    16         System.out.println(list);//排序之前的list
    17         
    18         list.sort(new Comparator<Integer>() {//使用Comparator进行自然排序
    19             @Override
    20             public int compare(Integer one, Integer anotherOne) {
    21                 int compareTo = one.compareTo(anotherOne);//正序排序
    22                 //int compareTo = anotherOne.compareTo(one);//逆序排序
    23                 
    24                 //比较结果为1则不操作
    25                 //比较结果为0则相等
    26                 //比较结果为-1则交换位置
    27                 System.out.println(anotherOne + "  --  " + one + "   ---   " + compareTo);
    28                 return compareTo;
    29             }
    30         });
    31         System.out.println(list);//排序之后的list
    32     }
    33 }

    运行结果:

    2、依照比较的结果(-1,0,1)进行判断分组

      示例代码如下:Apple类

     1 package com.FM.ArrayListStudy;
     2 
     3 public class Apple {
     4 
     5     private Integer id;
     6     private Integer size;
     7 
     8     public Integer getId() {
     9         return id;
    10     }
    11 
    12     public void setId(Integer id) {
    13         this.id = id;
    14     }
    15 
    16     public Integer getSize() {
    17         return size;
    18     }
    19 
    20     public void setSize(Integer size) {
    21         this.size = size;
    22     }
    23 
    24     public Apple(Integer id, Integer size) {
    25         super();
    26         this.id = id;
    27         this.size = size;
    28     }
    29 
    30     @Override
    31     public String toString() {
    32         return "Apple [id=" + id + ", size=" + size + "]";
    33     }
    34 
    35 }

      示例代码如下:利用Comparator接口分组

     1 package com.FM.ArrayListStudy;
     2 
     3 import java.util.ArrayList;
     4 import java.util.Comparator;
     5 import java.util.List;
     6 
     7 public class ComparatorInArrayListStudy02 {
     8     public static void main(String[] args) {
     9         ArrayList<Apple> list = new ArrayList<Apple>();
    10         list.add(new Apple(1, 81));
    11         list.add(new Apple(2, 76));
    12         list.add(new Apple(3, 91));
    13         list.add(new Apple(4, 84));
    14         list.add(new Apple(5, 79));
    15         list.add(new Apple(6, 87));
    16         list.add(new Apple(7, 85));
    17         list.add(new Apple(8, 83));
    18         list.add(new Apple(9, 91));
    19         System.out.println(list);//排序之前的list
    20         
    21         List<List<Apple>> disPartList = disPart(list,new Comparator<Apple>(){
    22             @Override
    23             public int compare(Apple o1, Apple o2) {//这里写具体的分组接口,分组方式可以使用对象内的属性的组合方式
    24                 if(o1.getSize()/10 == o2.getSize()/10){//将苹果Apple按照size分组,每10个size分为一组
    25                     return 0;
    26                 }
    27                 return 1;
    28             }
    29         });
    30         for(List lis : disPartList){//分别遍历每一组
    31             System.out.println(lis);
    32         }
    33     }
    34 
    35     /**
    36      * 按照comparator进行分组的方法
    37      */
    38     public static <T> List<List<T>> disPart(List<T> list, Comparator<? super T> c) {
    39         ArrayList<List<T>> resultList = new ArrayList<List<T>>();
    40         for (T t : list) {
    41             boolean flag = false;
    42             for (int i = 0; i < resultList.size(); i++) {
    43                 if (c.compare(t, resultList.get(i).get(0)) == 0) {// 若匹配成功则加入resultList中的子元素
    44                     flag = true;
    45                     resultList.get(i).add(t);
    46                     break;
    47                 }
    48             }
    49             if (flag == false) {// 若flag为false则将此元素加入resultList为新元素
    50                 List<T> listIn = new ArrayList<T>();
    51                 listIn.add(t);
    52                 resultList.add(listIn);
    53             }
    54         }
    55         return resultList;
    56     }
    57 }

    运行结果:

    分组的方式很多,很多人也喜欢自己写遍历来分组

    利用好Comparator接口进行分组能更好的重用,也更容易扩展!

     

    以上!!

  • 相关阅读:
    Heritrix 3.1.0 源码解析(二十五)
    Heritrix 3.1.0 源码解析(二十八)
    获取某年某月的第一天和最后一天的Sql Server函数
    C# ToString()用法汇总
    数据库隐式类型转换
    sql server 中 SET identity_insert on
    Linq To DataTable
    ASP.NET Session详解[转载]
    CSS overflow 属性
    HTML相对路径(Relative Path)和绝对路径(Absolute Path)
  • 原文地址:https://www.cnblogs.com/liuyuhangCastle/p/9704059.html
Copyright © 2020-2023  润新知