Java数组扩容的原理
1)、Java数组对象的大小是固定不变的,数组对象是不可扩容的。
2)、System.arraycopy()能够对数组进行扩容。
3)、Arrays.copyOf()能够简便的创建副本的同时能扩容也能缩容。
4)、创建数组副本的同一时候将数组长度添加就变通的实现了数组的扩容。
/**
* 2、数组扩容
*/
//定义一个整型数组
int[] array = {10,20,30,40,50};
array = Arrays.copyOf(array,4);
System.out.println("copyOf方法缩容:" + Arrays.toString(array));
array = Arrays.copyOf(array,5);
System.out.println("copyOf扩容:" + Arrays.toString(array));
(1)那让我看一下Arrays.copyOf()的源码,你会发现特别神奇之处
*
* @param original the array to be copied
* @param newLength the length of the copy to be returned
* @return a copy of the original array, truncated or padded with zeros
* to obtain the specified length
* @throws NegativeArraySizeException if newLength is negative
* @throws NullPointerException if original is null
* @since 1.6
*/
public static int[] copyOf(int[] original, int newLength) {
int[] copy = new int[newLength];
System.arraycopy(original, 0, copy, 0,
Math.min(original.length, newLength));
return copy;
}
是的,Array.copyOf()方法里面使用了System.arraycopy()方法,并且方法里面最后一个使用到Math.min(a,b)方法,这个方法目的是为了取a,b之间最小的那个数;当复制的元素的个数大于目标元素时,会有ArrayIndexOutOfBoundsException异常,即数组下标越界异常:
(2)我们随便写一个System.arraycopy()的方法,代码如下:
int[] newArr =arrayCopy(array,10);
System.out.println("数组扩容arraycopy:" + Arrays.toString(newArr));
}
private static int[] arrayCopy(int[] orignal, int length) {
int[] newArr = new int[length];
System.arraycopy(orignal,0,newArr,0,Math.min(orignal.length,length));
return newArr;
}
我们也需要在System.arraycopy()方法的最后一个参数增加Math.min(a,b)方法,目的如上已经说明,这样一个数组的扩容就可以很好实现了。
(3)我们再来说一个数组范围截取元素的方法--Arrays.copyOfRange(a,from,to),a代表需要截取的数组,from表示从数组第几个元素开始(包括此from),to表示截至到几个元素(不包括此to),上代码:
array = Arrays.copyOfRange(array,2,8);
System.out.println("截取范围copyOfRange方法:" + Arrays.toString(array));
*
* @param original the array from which a range is to be copied
* @param from the initial index of the range to be copied, inclusive
* @param to the final index of the range to be copied, exclusive.
* (This index may lie outside the array.)
* @return a new array containing the specified range from the original array,
* truncated or padded with zeros to obtain the required length
* @throws ArrayIndexOutOfBoundsException if {@code from < 0}
* or {@code from > original.length}
* @throws IllegalArgumentException if from > to
* @throws NullPointerException if original is null
* @since 1.6
*/
public static int[] copyOfRange(int[] original, int from, int to) {
int newLength = to - from;
if (newLength < 0)
throw new IllegalArgumentException(from + " > " + to);
int[] copy = new int[newLength];
System.arraycopy(original, from, copy, 0,
Math.min(original.length - from, newLength));
return copy;
}
上面的比较简单一些,也很容易掌握。
作为一个合格的程序员,一定要学会看源码,更重要的是坚持看源码,养成一个好的习惯,从他们的经验中能学到许多珍贵的程序理念。笔者最近在看mybatis的源码,受益匪浅,假以时日也一并奉上。
如果,你们感觉我写的还可以,请一定要给个赞,你们的赞扬是我最大的动力;当然,如果感觉写的差强人意,请不吝赐教。