list元素排序須要知足兩個條件

關於List

  說到list,個人印象就是單值集合接口,插入取出是有序的,容許重複,用他的實現類用的最頻繁的就是ArrayList了。若是我如今有一個list,插入了一些值,想讓裏面的值按照我自定義的規則排序。數組

如下測試基於JDK1.7ide

 ①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接口;this

下面是跟蹤Arrays.sort(a)的源碼spa

 

接下來看看String實現了Comparable接口,是怎麼實現它裏面惟一的方法的code

 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的排序規則。blog

 ② 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升序排序。

相關文章
相關標籤/搜索