A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© Victory8280 中级黑马   /  2015-11-5 22:06  /  355 人查看  /  3 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

ArrayList
以数组实现。节约空间,但数组有容量限制。超出限制时会增加50%容量,用System.arraycopy()复制到新的数组,因此最好能给出数组大小的预估值。默认第一次插入元素时创建大小为10的数组。
按数组下标访问元素--get(i)/set(i,e) 的性能很高,这是数组的基本优势。
直接在数组末尾加入元素--add(e)的性能也高,但如果按下标插入、删除元素--add(i,e), remove(i),remove(e),则要用System.arraycopy()来移动部分受影响的元素,性能就变差了,这是基本劣势。
LinkedList
以双向链表实现。链表无容量限制,但双向链表本身使用了更多空间,也需要额外的链表指针操作。
按下标访问元素--get(i)/set(i,e) 要悲剧的遍历链表将指针移动到位(如果i>数组大小的一半,会从末尾移起)。
插入、删除元素时修改前后节点的指针即可,但还是要遍历部分链表的指针才能移动到下标所指的位置,只有在链表两头的操作--add(), addFirst(),removeLast()或用iterator()上的remove()能省掉指针的移动。
CopyOnWriteArrayList
并发优化的ArrayList。用CopyOnWrite策略,在修改时先复制一个快照来修改,改完再让内部指针指向新数组。
因为对快照的修改对读操作来说不可见,所以只有写锁没有读锁,加上复制的昂贵成本,典型的适合读多写少的场景。如果更新频率较高,或数组较大时,还是Collections.synchronizedList(list),对所有操作用同一把锁来保证线程安全更好。
增加了addIfAbsent(e)方法,会遍历数组来检查元素是否已存在,性能可想像的不会太好。
补充
无论哪种实现,按值返回下标--contains(e), indexOf(e), remove(e) 都需遍历所有元素进行比较,性能可想像的不会太好。
没有按元素值排序的SortedList,在线程安全类中也没有无锁算法的ConcurrentLinkedList,凑合着用Set与Queue中的等价类时,会缺少一些List特有的方法。

3 个回复

倒序浏览
还不错呀。。。。。。
回复 使用道具 举报
不错啊,,
回复 使用道具 举报
总结例子讲会更好
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马