关于list的排序你真的会吗

关于List

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

 ①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     } 

猜你喜欢

转载自www.cnblogs.com/liyong888/p/9861131.html