关于数组性能,可变数组

1.性能考虑,数组首先

       比如这样一个场景,数据集求和

public static int sum(int[] datas) {
		int sum = 0;
		for (int i = 0; i < datas.length; i++) {
			sum += datas[i];
		}
		return sum;
}

        对于一个int类型数组求和,取出所有的数组元素并相加,此算法中如果是基本类型则使用数组效率是最高的,使用集合次之。再看看List求和:

public static int sum(List<Integer> datas) {
		int sum = 0;
		for (int i = 0; i < datas.size(); i++) {
			sum += datas.get(i);
		}
		return sum;
}

        sum+=datas.get(i)这条代码,其实做了一个拆箱动作,Integer对象通过intValue方法自动转换成一个int基本类型,对于性能濒于临界的系统来说该方案是比较危险的,特别是大数量的时候,首先,在初始化List数组要进行装箱动作,把一个int类型包装一个Integer对象,虽然它有整型池在,但不在整型池范围都会产生一个新的Integer对象,而且众所周知,基本类型是在栈内存中操作的,而对象则是在堆内存操作的,栈内存的特点是速度快,容积小,堆内存的特点是速度慢,容量大(从性能来上讲,基本类型的处理占优势)。其次,在进行求和计算(或者其他遍历计算)时要做拆箱动作,因此无所谓性能消耗也就产生了。

        在实际测试中发现:对基本类型进行求和计算时,数组效率是集合的是10倍。

1.若有必要,使用变长数组

        Java中数组是定长的,一旦经过初始化声明就不可变长度,这在实际使用中非常不方便,比如要对班级学生的信息进行统计,因为我们不知道一个班级有多少学生(随时都可能有学生入学,退学或转学)。所以需要一个足够大的数组来容纳所有学生,但问题是多大才算大呢?

public static <T> T[] expandCapacity(T[] datas, int newLen) {
		// 不能是负值
		newLen = newLen < 0 ? 0 : newLen;
		// 生成一个数组 并拷贝原值
		return Arrays.copyOf(datas, newLen);
}

        上述代码中采用的是Arrays数组工具类的copyOf方法,产生一个newLen长度的新数组,并把原有值拷贝了进去,之后就可以超长的元素进行赋值了(依据类型的不同分别赋值0.false,或null)如下代码:

public static void main(String[] args) {
		//一个班级最多容纳60个学生
		Student[] classes = new Student[60];
		//偶尔一个班级可以容纳80人,数组加长
		classes = expandCapacity(classes, 20);
		/*重新初始化超过限额的20人。。。。。。*/
}

        通过这样的处理方式,曲折的解决了数组变长的问题。其实,集合的长度自动维护功能的原理与此类似。在实际开发中,如果需要变长的数据集,数组也是在考虑范围之内的,不能因固定长度而将其否定之

猜你喜欢

转载自blog.csdn.net/hqbootstrap1/article/details/81322246