栏目导航
热点推荐
- 三十条有用的 Java 编程规则
- Java制作水印图片源码
- Java常见异常及可能的导致原因
- Java中的修饰词使用方法总结
- J2EE系统异常的处理准则
- Java中的异常、断言、日志解析(
- Java面试技巧:Java面试题集锦(
- 面向Java开发人员的Scala指南:
- Java程序员:一刻钟精通正则表达
- 网友经验分享:学好java开发的关
- 专家解答:创建表格与数据库进行
- Java远程访问Domino数据库
阅览排行
关于ArrayList的初始容量以及扩容的效率问题
www.jz123.cn 2010-03-11 来源: 中国建站 责任编辑(袁袁) 我要投递新闻
有这样一段很简单的代码:
ArrayList a = new ArrayList (); a.addAll(b); a.addAll(c); |
其中DataVO是一个实体类,b和c都是一个ArrayList
如果当b,c数据量很大的时候,请问这样一段代码是不是会很影响效率?
我们看一下ArrayList的源代码
view plaincopy to clipboardprint? public ArrayList() { s(10); } public ArrayList() { this(10); } 可见默认的构造器,其调用了参数为10的构造函数 view plaincopy to clipboardprint? public ArrayList(int initialCapacity) { er(); if (initialCapacity < 0) throw new IllegalArgumentException("Illegal Capacity: "+ initialCapacity); s.elementData = new Object[initialCapacity]; } public ArrayList(int initialCapacity) { super(); if (initialCapacity < 0) throw new IllegalArgumentException("Illegal Capacity: "+ initialCapacity); this.elementData = new Object[initialCapacity]; } |
这个带参数的构造函数,初始化了一个长度为初始容量的数组。
再看看add方法
view plaincopy to clipboardprint? public boolean add(E e) { ensureCapacity(size + 1); // Increments modCount!! elementData[size++] = e; return true; } public boolean add(E e) { ensureCapacity(size + 1); // Increments modCount!! elementData[size++] = e; return true; } |
这里面的第一行,就是确信当前容量是否能容下新增加的对象
public void ensureCapacity(int minCapacity) { modCount++; int ldCapacity = elementData.length; if (minCapacity > oldCapacity) { Object oldData[] = elementData; int newCapacity = (oldCapacity * 3)/2 + 1; if (newCapacity < minCapacity) newCapacity = minCapacity; // minCapacity is usually close to size, so this is a win: elementData = Arrays.copyOf(elementData, newCapacity); } } public void ensureCapacity(int minCapacity) { modCount++; int ldCapacity = elementData.length; if (minCapacity > oldCapacity) { Object oldData[] = elementData; int newCapacity = (oldCapacity * 3)/2 + 1; if (newCapacity < minCapacity) newCapacity = minCapacity; // minCapacity is usually close to size, so this is a win: elementData = Arrays.copyOf(elementData, newCapacity); } } |
此方法里,一旦发现容量不足,会自动扩充容量,新的大小是
view plaincopy to clipboardprint? int newCapacity = (oldCapacity * 3)/2 + 1; int newCapacity = (oldCapacity * 3)/2 + 1; |
也就是原有容量的1.5倍+1。然后通过底层的复制方法将原有数据复制过来
view plaincopy to clipboardprint? elementData = Arrays.copyOf(elementData, newCapacity); elementData = Arrays.copyOf(elementData, newCapacity); |
总结:
如果数据量很大,那么造成数组重新分配的次数会增加,但对于一般的数据量下,
1千需要分配 11次
1万一级需要分配17次
10万 需要分配23次
100万需要分配28次
所以,大家根据实际情况,大致分配一个初始化的容量还是有必要的。但是如果你初始容量太大,而数据增长很慢,那么就在浪费内存了。
如何取舍,还是看具体的应用场景了。
0
上一篇:Java程序异常处理的特殊情况 下一篇:一个Java项目的开发流程