Arraylist底层是数组,他用来存储数据,当个我们存储的是基本类型,int long boolean,short,byte时,存储的是他们的包装类,他的主要底层实现是Object[] elementData。
它的主要特点是查询快,增删慢。
总结:查询快,增删慢,线程不安全。
为啥线程不安全,还使用它呢?
因为我们正常使用的场景,都是用来查询,不会涉及频繁的增删,如果涉及频繁的增删,可以用LinkedList.
数组的长度是有限制的,而ArrayList是可以存放任意数量对象,长度不受限制,那么他是怎么实现的呢?
arraylist底层默认数组长度是10.当添加的长度超过限制时,会进行扩容,将其扩容成10+10/2=15.再将原数组移入新数组,
我记得你说到了,他增删很慢,你能说一下ArrayList在增删的时候是怎么做的么?主要说一下他为啥慢。
例:新增的时候先去判断一下数组的长度是否足够,如果不足,将会进行扩容,在足够的情况下,先将要新增位置及其后的内容进行复制,然后插入元素,再将复制内容放入插入元素后。(要移动插入后的所有元素和有可能扩容,所以慢)
删除的时候也是复制,将要删除元素的下一位元素及其后元素复制往前移动一行,覆盖原位置的元素。
ArrayList(int initialCapacity)会不会初始化数组大小?
会,但是List的大小没有变,因为list的大小是返回size的。
所以
size输出的是0,set也无法set进去。(用add可以添加元素)
ArrayList插入删除一定慢么?
取决于你插入元素的离末端有多远,
ArrayList是线程安全的么?
Arraylist是不安全的,我们可以使用Collections.synchronizedList把ArrayList包装成一个线程安全的数组容器。
ArrayList用来做队列合适么?
不适合,队列一般是先入先出的,而Arraylist一般是先入后出。
ArrayList用来做队列合适么?
队列一般是FIFO(先入先出)的,如果用ArrayList做队列,就需要在数组尾部追加数据,数组头部删除数组,反过来也可以。
但是无论如何总会有一个操作会涉及到数组的数据搬迁,这个是比较耗费性能的。
结论:ArrayList不适合做队列。
那数组适合用来做队列么?
数组是非常合适的。
比如ArrayBlockingQueue内部实现就是一个环形队列,它是一个定长队列,内部是用一个定长数组来实现的。
另外著名的Disruptor开源Library也是用环形数组来实现的超高性能队列,具体原理不做解释,比较复杂。
简单点说就是使用两个偏移量来标记数组的读位置和写位置,如果超过长度就折回到数组开头,前提是它们是定长数组。
ArrayList的遍历和LinkedList遍历性能比较如何?
论遍历ArrayList要比LinkedList快得多,ArrayList遍历最大的优势在于内存的连续性,CPU的内部缓存结构会缓存连续的内存片段,可以大幅降低读取内存的性能开销。