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