大家好,我是IT修真院郑州分院第8期学员,一枚正直善良的java程序员。今天给大家分享一下,修真院官网 java任务中可能会使用到的知识点:
ArrayList浅析
width="640" height="498" src="https://v.qq.com/iframe/player.html?vid=b0770ww5e8a&tiny=0&auto=0" allowfullscreen="">
【修真院java小课堂】ArrayList浅析20180829
1.背景介绍
- ArrayList就是动态数组,用MSDN中的说法,就是Array的复杂版本
- ArrayList提供了动态的增加和减少元素,实现了Collection和List接口,可以灵活的设置数组的大小。
- 要注意的是ArrayList并不是线程安全的,因此一般建议在单线程中使用ArrayList。
2.知识剖析
2.1 ArrayList重要的方法和特性
构造器
- ArrayList():构造一个初始容量为10的空列表。这个10在源码中没找到,但是在jdk官网找到了
- https://docs.oracle.com/javase/7/docs/api/java/util/ArrayList.html#ArrayList()
- ArrayList(Collection c):按照集合的迭代器返回的顺序构造一个包含指定集合元素的列表。
- ArrayList(int initialCapacity):构造具有指定初始容量的空列表。
2.2 ArrayList线程不安全
- 如果多个线程同时访问ArrayList实例,并且至少有一个线程在结构上修改了列表,则 必须在外部进行同步。
2.3 其他方法
- add()、set()、clear()
- 对于代码中的资源其实无外乎也是 创建、销毁、增删改查
- 其实就目前来说,基本上我们对数据库(持久化资源)以及代码中的某个对象所作的操作都是上边说的
- 个人感觉:所有的操作其实都是在对资源进行操作,创建–>增删改查–>销毁
3.常见问题
3.1 ArrayList的使用建议
- ArrayList是基于数组实现的,而LinkedList是基于链表实现的;
- 数组是将元素在内存中连续存放,由于每个元素占用内存相同,可以通过下标迅速访问数组中任何元素
- 链表恰好相反,链表中的元素在内存中不是顺序存储的,而是通过存在元素中的指针联系到一起。搜索不易
- 如果应用需要快速访问数据,很少或不插入和删除元素,就应该用数组,也就是ArrayList;
- 如果应用需要经常插入和删除元素你就需要用链表数据结构了,也就是LinkedList。
* 3.2 关于面试中的几个问题*
ArrayList的大小是如何自动增加的?你能分享一下你的代码吗?
- 这是最有技巧性的的一个问题,大多数人都无法回答。事实上,当有人试图在arraylist中增加一个对象的时候,Java会去检查arraylist,以确保已存在的数组中有足够的容量来存储这个新的对象。如果没有足够容量的话,那么就会新建一个长度更长的数组,旧的数组就会使用Arrays.copyOf方法被复制到新的数组中去,现有的数组引用指向了新的数组。可以看源码
如何复制某个ArrayList到另一个ArrayList中去?写出你的代码?
- 1.使用clone()方法,比如ArrayList newArray = oldArray.clone();
- 2.使用ArrayList构造方法,比如:ArrayList myObject = new ArrayList(myTempObject);
- 3.使用Collection的copy方法。
4.编码实战
- 简单看下源码以及使用
- 具体见视频
5.扩展思考
5.1 ArrayList扩容
- ArrayList是动态的,那么就允许增长自身的长度,这种情况下必须有扩容机制存在
- 按照当前容量的1.5倍扩容,直接看源码(见视频)
6.参考文献
https://docs.oracle.com/javase/7/docs/api/java/util/ArrayList.html
http://www.cnblogs.com/rickie/articles/67978.html
https://blog.csdn.net/xiaodaiye/article/details/50818966
https://www.cnblogs.com/kuoAT/p/6771653.html
7.更多讨论
Q:ArrayList是线程不安全的,那么想保证线程安全应该用什么?
A:Vector类的所有方法都是同步的,可以由多线程安全的访问一个Vector对象
Q:ArrayList删除的速度较慢,为什么?
A:因为ArrayList在删除的时候,需要将该元素之后的所有元素全部往前移,也就是说除了删除这个元素之外,还需要做很多额外的操作,所以耗时较久
Q:ArrayList的容量必须满足1.5倍扩容么?
A:是的,因为源码中已经写死了相关机制。
//以下为源码
private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;
//分析这一步,就可以得出新容量值是旧容量值的1.5倍
int newCapacity = oldCapacity + (oldCapacity >> 1);
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
// minCapacity is usually close to size, so this is a win:
elementData = Arrays.copyOf(elementData, newCapacity);
}