关于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. @Test
  28. public void fun1() {
  29. List<Person> listStrs = new LinkedList<Person>();
  30. listStrs.add(new Person("zhangsan", 20));
  31. listStrs.add(new Person("lisi", 28));
  32. listStrs.add(new Person("wangwu", 24));
  33. for (Person p : listStrs) {
  34. System.out.println(p);
  35. }
  36. System.out.println("我排序之后:");
  37. Collections.sort(listStrs, new Comparator<Person>() {
  38.  
  39. @Override
  40. public int compare(Person p1, Person p2) {
  41.  
  42. return p1.age - p2.age;
  43. }
  44. });
  45.  
  46. for (Person p : listStrs) {
  47. System.out.println(p);
  48. }
  49. }

我采用的是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. @Test
  40. public void fun2() {
  41. List<Person> listStrs = new LinkedList<Person>();
  42. listStrs.add(new Person("zhangsan", 20));
  43. listStrs.add(new Person("lisi", 28));
  44. listStrs.add(new Person("wangwu", 24));
  45. for (Person p : listStrs) {
  46. System.out.println(p);
  47. }
  48. System.out.println("我排序之后:");
  49. Collections.sort(listStrs);
  50.  
  51. for (Person p : listStrs) {
  52. System.out.println(p);
  53. }
  54. }

总结:

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

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

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

  

list元素排序需要满足两个条件的更多相关文章

  1. 《Algorithms算法》笔记:元素排序(1)——简单排序

    <Algorithms算法>元素排序(1)——简单排序 Algorithms算法元素排序1简单排序 排序问题 1 回调函数 2Java中回调函数的路线图 3 全序 4 Comparable ...

  2. Python对列表中字典元素排序

    问题起源 json对象a,b a = '{"ROAD": [{"id": 123}, {"name": "no1"}]} ...

  3. PAT 甲级 1053 Path of Equal Weight (30 分)(dfs,vector内元素排序,有一小坑点)

    1053 Path of Equal Weight (30 分)   Given a non-empty tree with root R, and with weight W​i​​ assigne ...

  4. Python小白干货宝典:sorted()函数:列表元素排序

    定义: sorted() 函数对所有可迭代的对象进行排序操作. 内建函数 sorted 方法返回的是一个新的 list,而不是在原来的基础上进行的操作. 语法: sorted 语法: sorted(i ...

  5. H5 60-浮动元素排序规则

    60-浮动元素排序规则 <!DOCTYPE html><html lang="en"><head> <meta charset=" ...

  6. Python对List中的元素排序

    首先定义一个compare函数: def compare(sf1, sf2): if (sf1.value > sf2.value): return -1; elif (sf1.value == ...

  7. Atitit 如何创新 创新只有在两种条件下发生:自由、效率。

    Atitit 如何创新 创新只有在两种条件下发生:自由.效率. 创新是如何发生的呢? 创新只有在两种条件下发生:自由.效率.在自由的环境下,对效率的追逐等于创新.如果你不自由,你的思想不够开阔,你脑洞 ...

  8. SortedSet的实现类是TreeSet:它的作用是字为添加到TreeSet中的元素排序。

      SortedSet可自动为元素排序. SortedSet的实现类是TreeSet:它的作用是字为添加到TreeSet中的元素排序.   练习:自定义类用TreeSet排序. 与HashSet不同, ...

  9. 《Algorithms算法》笔记:元素排序(4)——凸包问题

    <Algorithms算法>笔记:元素排序(4)——凸包问题 Algorithms算法笔记元素排序4凸包问题 凸包问题 凸包问题的应用 凸包的几何性质 Graham 扫描算法 代码 凸包问 ...

随机推荐

  1. git练习

    git commit 提交记录 git branch <branch_name> 建立名为branch_name的分支 git checkout <name>:git comm ...

  2. [Android] 开源框架 xUtils HttpUtils 代理设置 (Temporary Redirect错误)

    今天简单学习了一下xUtils的使用 https://github.com/wyouflf/xUtils 其中用到HttpUtils模块时,发现总是出现Temporary Redirect 错误. 查 ...

  3. IOS 十位数0补齐

    NSCalendar *calendar = [NSCalendar currentCalendar]; unsigned unitFlags = NSYearCalendarUnit | NSMon ...

  4. C++编译遇到参数错误(cannot convert parameter * from 'const char [**]' to 'LPCWSTR')

    转:http://blog.sina.com.cn/s/blog_9ffcd5dc01014nw9.html 前面的几天一直都在复习着被实习落下的C++基础知识.今天在复习着上次创建的窗口程序时,出现 ...

  5. java利用反射机制判断对象的属性是否为空以及获取和设置该属性的值

    1.java利用反射机制判断对象的属性是否为空: Map<String,String> validateMap = new LinkedHashMap<String, String& ...

  6. 170310、Jenkins部署Maven多环境项目(dev、beta、prod)的参数设置

    使用Jenkins配置Git+Maven的自动化构建: http://blog.csdn.net/xlgen157387/article/details/50353317 在一个多开发和生产环境的项目 ...

  7. IDEA安装Python环境,并加入Anaconda环境

    为什么做这个事情? 1.首先,Anaconda中已经有各种科学计算环境,包括后面安装的tensorflow 2.通过IDEA中配置就达到了Scala.Python.Java同时运行的目的. Intel ...

  8. CSS 中 BEM命名方式

    BEM的意思就是块(block).元素(element).修饰符(modifier),是一种CSS Class 命名方法. 类似于: .block{} .block__element{} .block ...

  9. 《Django By Example》第十二章(终章) 中文 翻译 (个人学习,渣翻)

    书籍出处:https://www.packtpub.com/web-development/django-example 原作者:Antonio Melé (译者注:第十二章,全书最后一章,终于到这章 ...

  10. JavaScript学习(5)-Image对象和动态HTML

    JavaScript学习5 1.image 对象 对象引用 document.images[n] document.images["imageName"] document.ima ...