[改善Java代码]在明确的场景下,为集合指定初始容量
我们经常使用ArrayList,Vector,Hashmap等集合,一般都是直接用new跟上类名声明出一个集合来,然后使用add,remove,等方法进行操作,而且因为它们是自动管理长度的,所以不用我们特别费心超长问题,这确实是一个非常好的优点,但也有我们需要注意的事项.
下面以ArrayList为例深入了解一下Java是如何实现长度的动态管理的,先从add方法的阅读开始.
public boolean add(E e) {
ensureCapacity(size + 1);
elementData[size++] = e;
return true;
}
我们知道ArrayList是一个大小可变的数组,但它在底层使用的是数组存储(也就是elementData变量),而且数组是定长的,要实现动态长度必然要进行长度的扩展,ensureCapacity方法提供了此功能,代码如下:
public void ensureCapacity(int minCapacity) {
modCount++; //修改计数器
int oldCapacity = elementData.length;
//当前需要的长度超过了数组长度,进行扩容处理
if (minCapacity > oldCapacity) {
Object oldData[] = elementData;
//新的容量 = 旧容量 * 1.5 + 1
int newCapacity = (oldCapacity * 3)/2 + 1;
if (newCapacity < minCapacity)
newCapacity = minCapacity;
//数组拷贝,生成新的数组
elementData = Arrays.copyOf(elementData, newCapacity);
}
}
注意看新数组的长度计算方法,并不是增加一个元素,elementData的长度就加1,而是在达到了elementData长度的临界点时,才将elementData扩容1.5把倍,这样实现有什么好处呢?好处就是避免了多次调用copyOf()方法的性能开销,否则每增加一个元素都要扩容一次,那性能岂不是非常的糟糕.
为什么是1.5倍呢,因为一次扩容太大,占用的内存也就越大,浪费的内存也就越多(1.5倍扩容,最多浪费33%的数组空间,而2.5倍扩容则最多浪费60%的内存),而扩容太小(比如每次扩容1.1倍),则需要多次对数组重新分配内存,性能消耗严重,经过测试验证,扩容1.5倍即满足了性能要求,也减少了内存消耗.
elementData的默认长度是10,如果我们使用默认的方式生命ArrayList,如new ArrayList(),则elementData的初始长度就是10.我们来看ArrayList的无参构造:
// ArrayList无参构造函数。默认容量是10。
public ArrayList() {
this(10);
}
// ArrayList带容量大小的构造函数。
public ArrayList(int initialCapacity) {
super();
if (initialCapacity < 0)
throw new IllegalArgumentException("Illegal Capacity: "+
initialCapacity);
// 新建一个数组
this.elementData = new Object[initialCapacity];
}
默认初始化时声明了一个长度为10的数组 在通过add方法增加第11个元素时,ArrayList类就自动扩展了,新的elementData数组长度就是(10*3)/2 +1 也就是16,当增加到第17个元素时再次扩容为(16*3)/2+1 也就是25,以此类推,实现了ArrayList的动态数组管理.
[改善Java代码]在明确的场景下,为集合指定初始容量的更多相关文章
- Java提高篇(三五)-----Java集合细节(一):请为集合指定初始容量
集合是我们在Java编程中使用非常广泛的,它就像大海,海纳百川,像万能容器,盛装万物,而且这个大海,万能容器还可以无限变大(如果条件允许).当这个海.容器的量变得非常大的时候,它的初始容量就会显得很重 ...
- 改善java程序的151个建议--数组和集合
60.性能考虑,数组是首选,在基本类型处理方面.数组还是占优势的,并且集合类的底层也都是通过数组实现.建议在性能要求较高的场景中使用数组替代集合. 61.假设有必要.使用变长数组:我们能够通过对数组扩 ...
- Java中间(三十五)-----Java详细设置(一个):请指定初始容量设置
集合是我们在Java编程中使用很广泛的,它就像大海,海纳百川,像万能容器,盛装万物.并且这个大海,万能容器还能够无限变大(假设条件同意). 当这个海.容器的量变得很大的时候,它的初始容量就会显得很重要 ...
- JAVA代码设置selector不同状态下的背景
Selector设置button点击效果(详细)以及常见问题https://www.jianshu.com/p/a0ddba6d7969 Android 代码动态设置TextView的背景.颜色Sel ...
- [改善Java代码]使用构造块精炼程序
建议36: 使用构造代码块精炼程序 什么叫代码块(Code Block)?用大括号把多行代码封装在一起,形成一个独立的数据体,实现特定算法的代码集合即为代码块,一般来说代码块是不能单独运行的,必须要有 ...
- [改善Java代码]正确使用String,StringBuffer,StringBuilder
CharSequence接口有三个实现类与字符串有关:String,StringBuffer,StringBuffer.虽然它们都与字符串有关,但是其处理机制是不同的. String类是不可改变的量, ...
- [改善Java代码]易变业务使用脚本语言编写
建议16: 易变业务使用脚本语言编写 Java世界一直在遭受着异种语言的入侵,比如PHP.Ruby.Groovy.JavaScript等,这些“入侵者”都有一个共同特征:全是同一类语言—脚本语言,它们 ...
- [改善Java代码]不同的场景使用不同的泛型通配符
Java泛型支持通配符(Wildcard),可以单独使用一个"?"表示任意类,也可以使用extends关键字标识某一类(接口)的子类型,还可以使用super关键字标识某一类(接口) ...
- [改善Java代码]不同的列表选择不同的遍历方法
一.场景: 我们来看一个场景,统计一个省的各科高考科目考试的平均分. 当然使用数据库中的一个SQL语句就能求出平均值,不过这个不再我们的考虑之列,这里只考虑使用纯Java的方式来解决.(由于我的机器配 ...
随机推荐
- Spark生态之Spark Core
- cocos2d-x图片变灰或者变亮
//根据现有CCSprite,变亮和变灰 CCSprite* FlyLeaf::graylightWithCCSprite(CCSprite* oldSprite,bool isLight) { ...
- homework-02 最大子区域和
题目描述 题目建立上一个作业的题目基础上,上一次作业是要求在一个一维序列里找一个最大连续子串,这次task最基础的要求是在一个二维表里找一个最大连续子矩形,但是这次作业有若干个升级版,分别要求可以加入 ...
- Hibernate监听器
Hibernate的事件监听机制 Hibernate中的事件监听机制可以对Session对象的动作进行监听,一旦发生了特殊的事件,Hibernate就会执行监听器中的事件处理方法 在某些功能的设计中, ...
- hibernate注解@JoinTable说明
表关联(@JoinTable)注解说明:@Target({METHOD, FIELD})public @interface JoinTable{ String name() default &q ...
- linux性能问题(CPU,内存,磁盘I/O,网络)
一. CPU性能评估 1.vmstat [-V] [-n] [depay [count]] -V : 打印出版本信息,可选参数 -n : 在周期性循环输出时,头部信息仅显示一次 delay : 两次输 ...
- HDU1398Square Coins(母函数)
母函数介绍见另一篇随笔HDU1028Ignatius and the Princess III(母函数) #include<iostream> #include<stdio.h> ...
- ECSHOP数据表结构完整仔细说明教程
From:http://www.ecshop119.com/ecshopjc-868.html s_account_log //用户账目日志表 字段 类型 Null 默认 注释 log_id medi ...
- stl lower_bound upper_bound binary_search equal_range
自己按照stl实现了一个: http://www.cplusplus.com/reference/algorithm/binary_search/ 这里有个注释,如何判断两个元素相同: Two e ...
- Codeforces Round #332 (Div. 2) A. Patrick and Shopping 水题
A. Patrick and Shopping Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/5 ...