說到list,個人印象就是單值集合接口,插入取出是有序的,容許重複,用他的實現類用的最頻繁的就是ArrayList了。若是我如今有一個list,插入了一些值,想讓裏面的值按照我自定義的規則排序。數組
如下測試基於JDK1.7ide
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
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升序排序。