• list元素排序需要满足两个条件


    关于List

      说到list,我的印象就是单值集合接口,插入取出是有序的,允许重复,用他的实现类用的最频繁的就是ArrayList了。如果我现在有一个list,插入了一些值,想让里面的值按照我自定义的规则排序。

    以下测试基于JDK1.7

     ①list里面是String的情况

     1 public static void main(String[] args) {
     2         List<String> listStrs = new ArrayList<String>();
     3         listStrs.add("aba");
     4         listStrs.add("aba2111");
     5         listStrs.add("aba22");
     6         for (String s : listStrs) {
     7             System.out.println(s);
     8         }
     9  
    10                 Collections.sort(listStrs);  //排序操作
    11 
    12                 System.out.println("操作后");
    13         for (String s : listStrs) {
    14             System.out.println(s);
    15         }       
    16 }         
    17 console:
    18 aba
    19 aba2111
    20 aba22
    21 操作后
    22 aba
    23 aba2111
    24 aba22

    从打印结果可以看出,collections.sort(listStrs);是排序了的,看下sort方法的源码

    1 public static <T extends Comparable<? super T>> void sort(List<T> list) {
    2         Object[] a = list.toArray();
    3         Arrays.sort(a);
    4         ListIterator<T> i = list.listIterator();
    5         for (int j=0; j<a.length; j++) {
    6             i.next();
    7             i.set((T)a[j]);
    8         }
    9     }

    实际上就是把list转成数组,再执行Arrays.sort(a); sort源码就不看了,我简单跟了一下,实际上它是调用了ComparableTimSort.sort方法,继续跟下去最终会把数组a 转换成 Comparable接口:Comparable<Object> pivot = (Comparable) a[start];,到这里就可以解释为什么String类实现了Comparable接口;

    下面是跟踪Arrays.sort(a)的源码

    接下来看看String实现了Comparable接口,是怎么实现它里面唯一的方法的

     1 public int compareTo(String anotherString) {
     2         int len1 = value.length;
     3         int len2 = anotherString.value.length;
     4         int lim = Math.min(len1, len2);
     5         char v1[] = value;
     6         char v2[] = anotherString.value;
     7 
     8         int k = 0;
     9         while (k < lim) {
    10             char c1 = v1[k];
    11             char c2 = v2[k];
    12             if (c1 != c2) {
    13                 return c1 - c2;
    14             }
    15             k++;
    16         }
    17         return len1 - len2;
    18     }

    这个方法就是定义了排序的规则,返回负数则调换这两个数的顺序,返回正数和0不管,所以从代码中可以看到优先比较字符串中的字符大小,然后比较长度,这就是String的排序规则。

     ② list里面是普通实体类Person的情况

     1 public class Person{
     2         private String name;
     3         private int age;
     4         
     5         public Person(String name, int age) {
     6             super();
     7             this.name = name;
     8             this.age = age;
     9         }
    10         public String getName() {
    11             return name;
    12         }
    13         public void setName(String name) {
    14             this.name = name;
    15         }
    16         public int getAge() {
    17             return age;
    18         }
    19         public void setAge(int age) {
    20             this.age = age;
    21         }
    22         @Override
    23         public String toString() {
    24             return "Person [name=" + name + ", age=" + age + "]";
    25         }
    26 
    27 
    28     @Test
    29     public void fun1() {
    30         List<Person> listStrs = new LinkedList<Person>();
    31         listStrs.add(new Person("zhangsan", 20));
    32         listStrs.add(new Person("lisi", 28));
    33         listStrs.add(new Person("wangwu", 24));
    34         for (Person p : listStrs) {
    35             System.out.println(p);
    36         }
    37         System.out.println("我排序之后:");
    38         Collections.sort(listStrs, new Comparator<Person>() {
    39 
    40             @Override
    41             public int compare(Person p1, Person p2) {
    42                 
    43                 return p1.age - p2.age;
    44             }
    45         });
    46         
    47         for (Person p : listStrs) {
    48             System.out.println(p);
    49         }
    50     }

    我采用的是new Comparator()的方式才定义排序规则,规则比较简单,就是按照年龄升序

     也可以让Person类和String类玩一个套路,让他实现Comparable接口。

     1 public class Person<T> implements Comparable<T>{
     2         private String name;
     3         private int age;
     4         
     5         public Person(String name, int age) {
     6             super();
     7             this.name = name;
     8             this.age = age;
     9         }
    10         public String getName() {
    11             return name;
    12         }
    13         public void setName(String name) {
    14             this.name = name;
    15         }
    16         public int getAge() {
    17             return age;
    18         }
    19         public void setAge(int age) {
    20             this.age = age;
    21         }
    22         @Override
    23         public String toString() {
    24             return "Person [name=" + name + ", age=" + age + "]";
    25         }
    26         @Override
    27         public int compareTo(T o) {
    28             if(o instanceof Integer) {
    29                 return (Integer)o - age;
    30             }
    31             if(o instanceof Person) {
    32                 System.out.println("是啥:" + ((Person) o).getAge() + "this是啥:" + this.getAge());
    33                 return this.age - ((Person) o).getAge();
    34             }
    35             return 0;
    36         }
    37     }
    38 
    39 
    40 
    41     @Test
    42     public void fun2() {
    43         List<Person> listStrs = new LinkedList<Person>();
    44         listStrs.add(new Person("zhangsan", 20));
    45         listStrs.add(new Person("lisi", 28));
    46         listStrs.add(new Person("wangwu", 24));
    47         for (Person p : listStrs) {
    48             System.out.println(p);
    49         }
    50         System.out.println("我排序之后:");
    51         Collections.sort(listStrs);
    52         
    53         for (Person p : listStrs) {
    54             System.out.println(p);
    55         }
    56     } 

    总结:

      1 list默认是存取是有序的。

      2 要想让List按照自己定义的规则进行排序,需满足两点:① list中的元素实现Comparable接口,② Collections.sort(list)方法

      2 String类实现了Comparable接口,规则是按照字符串长度和字母a-z升序排序。

      

  • 相关阅读:
    2016_6_28日报
    2016_6_27日报
    软工总结
    团队项目:第九关攻略
    团队项目:第八关攻略
    团队项目:第七关攻略
    团队项目:第六关攻略
    团队项目:第五关攻略
    团队项目:第三四关攻略
    day5
  • 原文地址:https://www.cnblogs.com/liyong888/p/9861131.html
Copyright © 2020-2023  润新知