Java中Collections.sort()方法的演变-阿里云开发者社区

开发者社区> javaedge> 正文

Java中Collections.sort()方法的演变

简介: 先看一段代码 List list = new ArrayList(); list.add(1); list.add(2); list.add(3); Iterator it = list.
+关注继续查看

先看一段代码


  List<Integer> list = new ArrayList<Integer>();
  list.add(1);
  list.add(2);
  list.add(3);

  Iterator<Integer> it = list.iterator();

  Collections.sort(list);

  while (it.hasNext()) {
   System.out.println(it.next());
  }

Java7 运行效果

1
2
3

Java8 运行效果


img_242725c4c2491627ff9d29640736919f.png

结果分析

在上面的代码中,我们先得到list的iterator,然后对list进行排序,最后遍历iterator。
从Java8的错误信息中可以看出it.next( )方法中检查list是否已经被修改,由于在遍历之前进行了一次排序,所以checkForComodification方法抛出异常ConcurrentModificationException。
这个可以理解,因为排序,肯定会修改list
但是为啥Java7中没问题呢?

源码分析

首先看checkForComodification方法是如何判断的,如下所示:

final void checkForComodification() {
  if (modCount != expectedModCount)
    throw new ConcurrentModificationException();
}

可以看出,有两个内部成员变量用来判断是否发生了修改: modCount 和 expectedModCount。

Iterator中记录了expectedModCount
List中记录了modCount
checkForComodification方法通过比较modCount 和 expectedModCount来判断是否发生了修改。

在Java7中,Collections.sort( list )调用的是Collections自身的sort方法,如下所示:

public static <T extends Comparable<? super T>> void sort(List<T> list) {
   Object[] a = list.toArray();
   Arrays.sort(a);
   ListIterator<T> i = list.listIterator();
   for (int j=0; j<a.length; j++) {
     i.next();
     i.set((T)a[j]);
   }
}

可以看出,该排序算法只是改变了List中元素的值(i.set((T)a[j]);),并没有修改modCount字段。所以checkForComodification方法不会抛出异常。

而在Java8中,Collections.sort( list )调用的是ArrayList自身的sort方法,如下所示:

public static <T extends Comparable<? super T>> void sort(List<T> list) {
list.sort(null);
}
ArrayList的sort方法实现如下:


img_342cb895192ca95bb13330d613a84a5c.png

可以看出最后一行,modCount++修改了modCount字段
所以checkForComodification方法会抛出异常

关于Java8中Collections.sort方法的修改

之前,Collection.sort复制list中的元素以排序到数组中,对数组进行排序,然后使用数组中的元素更新列表,并将默认方法List.sort委托给Collection.sort。这不是一个最佳的设计
从8u20发布起,Collection.sort将被委托给List.sort,这意味着,例如,现有的以ArrayList实例调用Collection.sort的代码将使用由ArrayList实现的最佳排序

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
【Elastic Engineering】Elasticsearch 简介
Elasticsearch 是一个非常强大的搜索引擎。
3 0
安卓平板体验Java开发,还能白嫖一年阿里无影云!真香
阿里无影云早有耳闻,前两天看朋友发体验照片,可能是程序员天生爱折腾的特性又发挥作用了,自己也没能忍住,赶快下载体验了一把,没想到“很香”。我体验了浏览器端、Windows 客户端和安卓平板端,下面就来聊聊使用的过程和使用体验。内含一年免费无影云的白嫖方法,千万别错过哦~
22 0
阿里巴巴数据库分库分表的实践(5)
阿里巴巴数据库分库分表的实践(5)
4 0
飞天加速计划-服务器使用经历
自我介绍,阿里云服务器使用体验,总结收获,个人作品链接。
14 0
阿里巴巴数据库分库分表的实践(1)
阿里巴巴数据库分库分表的实践(1)
6 0
使用阿里云ECS搭建个人网站
学习在ECS上如何搭建个人网站
23 0
学习者的窘境:程序员如何有效学习才能有成就感
学习者的窘境:程序员如何有效学习才能有成就感
5 0
+关注
javaedge
关注公众号:JavaEdge,后台回复面试,领取更多大厂求职资源。曾在百度、携程、华为等大厂搬砖,专注Java生态各种中间件原理、框架源码、微服务、中台等架构设计及落地实战,只生产硬核干货!
2317
文章
1
问答
文章排行榜
最热
最新
相关电子书
更多
《2021云上架构与运维峰会演讲合集》
立即下载
《零基础CSS入门教程》
立即下载
《零基础HTML入门教程》
立即下载