相信绝大部分人在用 List 的时候用的都是 ArrayList,能用到 LinkedList 的情况都很少。
这里还有一个更冷门的 Vector 类,在这个类中有一个 Stack,stack 在一些特定的时候可能会用到。
因最近面试工作的需要,感觉有必要来看看 Vector 和 ArrayList。
有什么不同
可以简单的理解 Vector 和 ArrayList 是一样的,除了 ArrayList 不是线程安全之外。
那为什么有人会问,既然 Java 是多线程,Vector 又是线程安全的,为什么我们不用 Vector 反而要用 ArrayList 呢?
其实主要还是效率,对于很多程序,不一定会用到多线程,很多情况下都是单线程,如果用 Vector 来说效率没有 ArrayList 高,而且线程同步也用不上呀。
所以,你会看到 Java 中很多程序都是用的 ArrayList。
JDK 实现
既然说到这里,看看源代码不是坏事。
底层实现
底层实现,Vector 的底层实现也是数组,这个和 ArrayList 是一样的。
方法同步
对 List 来说,最重要的方法应该是 add 方法,因为你可能在创建好 List 以后就要添加数据了。
我们查看 Vector 的源代码后,会看到上面的添加元素方法有同步关键字。
因为有线程同步关键字,所以 Vector 的很多重要方法都是线程安全的。
这就是为什么说 Vector 被用在多线程中的原因。
扩容算法
List 和 Array 的最大区别就是我们可以不停的 Add 元素。
但是 List 的底层是用 Array 实现的,为什么我们可以这样不停的 Add 元素呢?
这是因为 List 会有一个扩容算法,当我们添加的元素超过了 List 当前的容量的时候,List 会帮我们自动进行扩容。
这里都会涉及到一个扩容算法。
ArrayList 默认的数组长度是 10,这个定义在了 DEFAULT_CAPACITY 常量中。
private static final int DEFAULT_CAPACITY = 10;
Vector 没有定义默认常量,那么一进来 Vector 可能就需要进行扩容算法了。
让我们来查看上面的方法,elementCount 直接 +1 了,换句话说,Vector 的扩容就比较简单粗暴了。
题外话
-XX:MaxInlineSize: 能被内联的方法的最大字节码大小 ,默认值为35Byte,这种方法不需要频繁的调用。
比如:一般pojo类中的getter和setter方法,它们不是那种调用频率特别高的方法,但是它们的字节码大小非常短,这种方法会在执行后被内联。
上面的方法被拆分了,主要目的是要方法小于 35Byte。
总结
对于日常的应用来说,我们通常不会进入到这么深入的了解这些具体的方法的实现。
对大部分来说,直接用上面的方法就可以了,当你有时间的时候,对具体的 JDK API 实现是可以花一点点的时间来进行研究的。
通过对实现的研究来了解别人是怎么写这些方法来达到目的,更主要是了解一些思路。
JDK 的源代码,有时候写得不是那么通俗易懂,但这也是一个学习的过程,不是吗?