JDK8源码学习笔记之一:ArrayList

JDK8源码学习笔记之一:ArrayList

本人英语与Java技术水平有限,难免会有疏漏,欢迎广大网友在平路中提出各类意见,还有,禁止说脏话,谢谢!

一、ArrayList.java 注释译文与解读

  • ArrayListList接口的一个容量大小可变数组的实现类。
  • ArrayList实现了所有List的可选方法,并且可以接受所有的元素,包括null元素。
  • ArrayList提供了方法来操作其内部数组大小,此数组负责存储ArrayList中的元素。
  • ArrayList除了线程不安全这一点,其他的几乎等同于Vector
  • ArrayList.size()/isEmpty()/get(i)/set(Object)/iterator()/listIterator()方法运行时间是一个静态常量(固定时长)。
  • ArrayList.add(Object)方法运行时间遵循恒定分摊时间,也就是说它的时间复杂度是O(n)。
  • ArrayList其他的方法的运行时间都是线性增长的,与容器内元素数量成正比。
  • 每一个ArrayList实例都包含CapacityCapacity代表了ArrayList中的容量,它最小等于ArrayList的容量大小。当一个元素被添加到ArrayList中时,ArrayListCapacity会自动增长。Capacity自动增长的方法运行时间复杂度是O(n)。
  • 如果需要向ArrayList Add大量元素,建议先通过ensureCapacity方法预设置Capacity大小。这样可以减少执行时间。通过查看Add方法源码,发现JDK在ArrayList无扩容的情况下,每次都创建一个OldSize+1的数组对象,因为size大小不够,每次都需要扩容。但是使用了ensureCapacity方法预设集合容量,就不需要每次add都扩容了,极大地降低了add方法的执行时间。
  • 注意!ArrayList是List接口的一个线程不安全的实现。如果多个线程并发地访问同一个ArrayList实例,而且至少有一个线程在结构上改变了此实例,那么一定要显示声明synchronized,这是一个处理并发问题的典型方法。(结构上修改主要是指,执行任意 add 或者 delete 或者显示重设内部数组大小。仅仅是为ArrayList中的元素赋值的话,那就不是结构修改。)
  • 如果ArrayList中存储的对象不是线程安全的,那么应该使用Collections.synchronizedList方法包装list—–为了避免突然的非同步访问,最好在创建ArrayList对象的时候就这么做!
 List list = Collections.synchronizedList(new ArrayList(...));
  • ArrayList.iterator()/listIterator(int)返回的迭代器对象(iterators) 是快速失败的(Fail-fast)。如果ArrayList的结构会随时被改变,只有iterator的 removeadd方法不会抛出 ConcurrentModificationException 异常。因此,在面对并发修改的情况系,迭代器会快速并且干净的失败,比在循环中出风险要强得多。
  • 注意!虽然迭代器拥有快速失败行为,但是未同步的并发修改问题很复杂,还是要谨慎使用。不能在生产环境使用 ConcurrentModificationException 异常,这个异常只能在debug模式下使用。

你可能感兴趣的:(jdk源码分析)