摘要

极客时间里的Java核心技术系列,第8讲,记录一些笔记。
关键词:线程安全、扩容、fast-fail、modCount、transient、迭代器、适配器。

ArrayList

觉得应该先来说说 ArrayList,再来说Vector。。。 他们很像。。。
  • 不是线程安全的。
  • 基于动态数组实现的,默认容量为10。
  • 存储元素的数组 elementData 用 transient 关键字来修饰,代表默认不能被 序列化
    但是可以用 ArrayList 里提供的 readObject( ) 和 writeObject( ) 方法来序列化 数组里有元素的那部分内容。
  • fast-fail机制:
    在进行序列化 或者 迭代等操作时,如果 modCount 这个变量改变了,就会抛 ConcurrentModificationException 异常。
    modCount (记录结构发生变化的变量):
    添加、删除、调整数组大小都会改变这个值。但是改变一个元素的值不算结构发生变化。
  • 在需要扩容的时候, 增量为 原来的一半。 最后是调用 Arrays.copyOf( ) 这个方法来进行数组的拷贝。
  • 在需要删除元素时, 底层是调用 System.arraycopy( ) 的native方法,时间复杂度为 O(N)。

Vector

和 ArrayList 很像,基于动态数组实现。默认容量为10。

  • 但 Vector 是线程安全的,简单粗暴的基于 synchronized 关键字来实现。

    要进行 synchronized 同步,所以开销就比较大,很少用了。
    替代方案有:

    • Collections.synchronizedList( ) 方法。
    • concurrent 包下的 CopyOnWriteArrayList 类。

      不适合
      对内存敏感(写时 是再开辟一块内存空间来写)

      对实时性要求很高(读时 可能写入的数据还未同步)
      的场景。

  • 在 扩容 时,可以通过 capacityIncrement 这个参数来选择增加的容量。
    默认情况下,增量 为原来的1倍。 之后也是调用 Arrays.copyOf( ) 这个方法来拷贝数组。

LinkedList

  • 不是线程安全的。

  • 基于 双向链表来实现的。
    进行 节点 的插入和删除要高效很多,但是 随机访问 就慢了。

  • 可以用作栈、队列、双向队列。

    存储结构:

Java 中关于 Collection 中的部分继承关系图:

集合中涉及到的设计模式

  • 迭代器模式: 提供一种方法顺序访问 聚合对象 的内部元素。
    Collection接口 是 继承自 Iterable 接口的。

  • 适配器模式: 把一个接口转换成用户需要的 另一个接口。
    Arrays.asList( ) 数组类型 转为 List 类型。

#参考链接:
https://blog.csdn.net/chenssy/article/details/38151189
https://wiki.jikexueyuan.com/project/java-enhancement/java-thirtysix.html
https://www.runoob.com/design-pattern/iterator-pattern.html

https://cyc2018.github.io/CS-Notes/#/notes/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%20-%20%E9%80%82%E9%85%8D%E5%99%A8