Java知识:ArrayList类详解
来源:互联网 发布:底盘装甲 知乎 编辑:程序博客网 时间:2024/06/15 19:46
1、ArrayList的本质是什么?
ArrayList本质是顺序表!
2、 什么是顺序表?
顺序表是在计算机内存中以数组的形式保存的线性表,是指用一组地址连续的存储单元依次存储数据元素的线性结构。只要确定了起始位置,表中任一元素的地址都通过下列公式得到:LOC(ai)=LOC(a1)+(i-1)*L 1≤i≤n 其中,L是元素占用存储单元的长度。
简单点说就是:以数组的形式保存的线性表(属于线性表中的一种)
3、ArrayList这个顺序表是如何实现的呢,证据呢?
ArrayList是通过数组实现的。ArrayList构造函数如下:
一下代码摘抄自JDK源码,我只摘抄了需要用到的部分。
private transient Object[] elementData;//声明了一个object类型的数组public ArrayList(int initialCapacity) { super(); if (initialCapacity < 0) throw new IllegalArgumentException("Illegal Capacity: "+ initialCapacity); this.elementData = new Object[initialCapacity];//创建了一个initialCapacity容量的数组 } /** * Constructs an empty list with an initial capacity of ten. */ public ArrayList() { this(10); }
在构造函数中有一句话this.elementData = new Object[initialCapacity];//创建了一个initialCapacity容量的数组
4、ArrayList初始容量是多少呢?
根据构造函数如果我们自定义了容量:ArrayList<String> al=new ArrayList<String>(20);那么容量就是20如果我们没有自定义容量:ArrayList<String> al=new ArrayList<String>();那么容量就是10
5、ArrayList扩容扩多少呢?
现在我们看看add操作
public boolean add(E e) { ensureCapacityInternal(size + 1); // Increments modCount!! elementData[size++] = e; return true; }
add操作的第一步就是执行ensureCapacityInternal方法。
private void ensureCapacityInternal(int minCapacity) { modCount++; // overflow-conscious code if (minCapacity - elementData.length > 0) grow(minCapacity); }
modCount++;这个一会儿会讲到
if (minCapacity - elementData.length > 0)
grow(minCapacity);//如果容量小了就执行grow(minCapacity)函数,看来grow(minCapacity)是扩容函数的庐山真面目啊
private void grow(int minCapacity) { // overflow-conscious code int oldCapacity = elementData.length; int newCapacity = oldCapacity + (oldCapacity >> 1);//扩容50% 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); }
newCapacity = oldCapacity + oldCapacity / 2;
就是说每次当发现当前数组长度不足时,每次增加的步长是【0.5倍的当前长度】。
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
比方说你有个10容量的数组,现在要通过addAll()方法增加10个元素,那么minCapacity就是20,newCapacity就是15,15小于20那么newCacacity就变成了20.也就是说此次扩容了100%。
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
如果你的newCapacity比MAX_ARRAY_SIZE(Integer.MAX_VALUE - 8)还要大的话就要看看 hugeCapacity(int minCapacity) 方法了;
private static int hugeCapacity(int minCapacity) { if (minCapacity < 0) // overflow throw new OutOfMemoryError(); return (minCapacity > MAX_ARRAY_SIZE) ? Integer.MAX_VALUE : MAX_ARRAY_SIZE; }
根据hugeCapacity(int minCapacity) 方法,newCapacity= Integer.MAX_VALUE
这次扩容的比例应该小于等于50%
网上有人说他每次扩容50%也是不准确的。
6、在ArrayList中我们经常看到modCount,这个变量有什么用呢?
这位大神给出了很好的解答:
http://blog.csdn.net/qq_24235325/article/details/52450331
这其实Fail-Fast机制快速失败机制,这个机制以后再发博客吧。
7、protected transient int modCount = 0;中的transient关键字有啥用呢?
transient 修饰的变量不会序列化,关于序列化的知识以后再详细说明吧。
8、ArrayList是基于动态数组实现的?
Java中的数组都是静态数组(数组大小不可变)。
那ArrayList是基于动态数组实现的是不正确的吗?
ArrayList实现动态数组本质的创建新的数组,只是看起来原来的数组动态增长了!
这句话的正确与否取决于你对动态数组的理解和认识,你认为之前有个数组,之后创建一个新的可以算作“动态”那这句话是正确的。
如果你认为创建了一个新的,原来的是”静态“的,那么这句话是不正确的。
这个问题没有必要较真。
9、ArrayList为什么是不同步的?
看看jdk里ArrayList的add方法是如何写的
问题就出在size++这边,主要分为两个步骤:
1)将add的元素放到size位置 2)将size加1
假设size=5.若线程A在5位置存放了值valueA,获得size=5,但还没来得及将size加1写入主存。此时线程B在也在5位置存放了值valueB,也获得size=5,而后A、B分别将size加1后写入主存,size=6,即两个线程执行两次add()后size只加了1。
总结:
1、ArrayList适合查找,不适合频繁的增删。
2、ArrayList不同步
3、如果可以确定ArrayList所需容量最好直接定义。
参考资料:
http://blog.csdn.net/li_ning_/article/details/52089861
http://www.cnblogs.com/dick159/p/6531004.html
http://www.cnblogs.com/shamo89/p/6672104.html
http://blog.csdn.net/qq_24235325/article/details/52450331
- Java知识:ArrayList类详解
- Java Arraylist知识
- Java中ArrayList类详解
- Java中ArrayList类详解
- Java中ArrayList类详解
- Java中ArrayList类详解
- Java中ArrayList类详解
- Java中ArrayList类详解
- java集合类详解--ArrayList
- Java中ArrayList类详解
- Java重要类详解之ArrayList类
- Java中容器类:ArrayList 详解
- JAVA语言ArrayList类使用实例详解
- Java中ArrayList类详解(转载)
- java学习之ArrayList容器类详解
- java ArrayList详解
- Java之ArrayList详解
- Java ArrayList详解
- 简单的文件管理器
- 1+2:组合迭代器
- Java 获取格林威志时间,和各个时间的关系
- 使用git上传项目到GitHub
- HDU 1398 找零钱
- Java知识:ArrayList类详解
- 欢迎使用CSDN-markdown编辑器
- SylixOS USB虚拟网卡框架
- EditText默认不弹出软件键盘
- 常用正则表达式汇总
- iOS-制作并调用Bundle资源包
- Android Recyclerview列表自动播放视频
- 去哪儿笔试:部分和问题 java
- Map