mvc做门户网站,免费下载访问迅雷网盘,建站之星安装说明,杭州软件建设数学问题#xff1a;newCapacity minCapacity 和 newCapacity - minCapacity 0 代表相同的含义吗#xff1f;答案#xff1a;是#xff0c;在计算机中不同#xff0c;因为数字用的是有限位的补码#xff0c;也正是因此才会有考虑溢出的代码。 private void …数学问题newCapacity minCapacity 和 newCapacity - minCapacity 0 代表相同的含义吗答案是在计算机中不同因为数字用的是有限位的补码也正是因此才会有考虑溢出的代码。 private void grow(int minCapacity) {// overflow-conscious codeint oldCapacity elementData.length;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);}
补码在表示有符号数的时候最高位用来当做符号位0代表正数1代表负数。
private static int hugeCapacity(int minCapacity) {if (minCapacity 0) // overflowthrow new OutOfMemoryError();return (minCapacity MAX_ARRAY_SIZE) ?Integer.MAX_VALUE :MAX_ARRAY_SIZE;}
最大值整数加1就会变成最小值整数。其实将int的这些数字看起来很像是一个圆环从0开始逆时针增大到最大值的时候再加1就变为最小值然后再逆时针增大到0。
具体如下
在jdk源码中会有很多考虑了溢出而编写的代码这些代码前会有注释overflow-conscious code说明下面这段代码是考虑了溢出的情况的。最经典的代码就是里ArrayList的grow方法
代码如下ArrayList.grow) package com.atcm.until;public class TestArrayList {/*** Default initial capacity.*/private static final int DEFAULT_CAPACITY 10;private static final int MAX_ARRAY_SIZE Integer.MAX_VALUE - 8;// transient Object[] elementData; // non-private to simplify nested class accessint length 0; // elementData的长度int capacity 0; // elementData的容量Object obj null;/*** The size of the ArrayList (the number of elements it contains).** serial*/private int size;public TestArrayList(){int length 0; // elementData的长度int capacity 0; // elementData的容量}public static void main(String[] args) {TestArrayList arrayList new TestArrayList();for (int i 0; i 100; i) {arrayList.add(数据);}}public boolean add(Object e) {ensureCapacityInternal(size 1); // Increments modCount!!//elementData[size] e;size;obj e;return true;}private void ensureCapacityInternal(int minCapacity) {//if (elementData DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {// minCapacity Math.max(DEFAULT_CAPACITY, minCapacity);//}minCapacity Math.max(DEFAULT_CAPACITY, minCapacity);ensureExplicitCapacity(minCapacity);}private void ensureExplicitCapacity(int minCapacity) {// overflow-conscious codeif (minCapacity - this.length 0) {System.out.println( 开始扩容);grow(minCapacity);println();}}/*** Increases the capacity to ensure that it can hold at least the* number of elements specified by the minimum capacity argument.** param minCapacity the desired minimum capacity*/private void grow(int minCapacity) {// overflow-conscious codeint oldCapacity this.length;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);capacity newCapacity; // 相当新数组length capacity; // 相当新数组替换旧数组}private static int hugeCapacity(int minCapacity) {if (minCapacity 0) // overflowthrow new OutOfMemoryError();return (minCapacity MAX_ARRAY_SIZE) ?Integer.MAX_VALUE :MAX_ARRAY_SIZE;}public void println() {if (size 0) {System.out.println(扩容结果size size length length capacity capacity);}else {System.out.println(扩容结果size size length length capacity capacity capacity/size 1.0 * capacity / size);}}
}这段模拟代码的功能是对ArrayList的存储进行扩容扩大为原来的1.5倍。那么在计算扩展后的容量时就有可能会溢出。 结果 开始扩容
扩容结果size 0 length10 capacity10开始扩容
扩容结果size 10 length15 capacity15 capacity/size1.5开始扩容
扩容结果size 15 length22 capacity22 capacity/size1.4666666666666666开始扩容
扩容结果size 22 length33 capacity33 capacity/size1.5开始扩容
扩容结果size 33 length49 capacity49 capacity/size1.4848484848484849开始扩容
扩容结果size 49 length73 capacity73 capacity/size1.489795918367347开始扩容
扩容结果size 73 length109 capacity109 capacity/size1.4931506849315068Process finished with exit code 0