java 复制数组的方法总结
2017-04-27 19:34
453 查看
在看ArrayList源码的时候出现了好多关于数组扩容(也就是复制数组的操作),如么如果换作我们,如何进行数组的复制操作呢
打印[4, 1, 2, 9, 10, 12, 15]复制成功
打印[4, 1, 2, 9, 10, 12, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],扩容成功
要是工作中老是遇到复制数组该怎么办呢?很简单,封装个静态方法不就可以了。等等,既然智商如我这么低的人都知道封装方法,那前辈们肯定封装好了,那就找一找呗
有意思的是Math.min(original.length, newLength);,会取原始数组长度和newLength的最小值
所以当newLength < original.length时,相当于对原始数组的截取
当newLength > original.length时,相当于对原始数组的扩容
当newLength == original.length时呢。别问我了,我不知道
原理介绍完了,使用方式和上面那个基本一样。
最不好理解的地方应该在
我发现在Java所有的截取操作中都是截头不截尾(包含from,不包含to),那么上述代码的意思就是从原数组的from处复制到copy数组,以0开始,复制Math.min(original.length - from, newLength)个
这个方法了,一个native方法
具体的用法是从src的srcPos处把length个长度的元素从dest的destPos处复制进dest数组里
我们可以用这个方法来复制数组
模拟ArrayList的add(int index, E e)操作
其实ArrayList的底层实现大体就像上面那样
for循环复制
我们首先想到的是for循环,来上代码int[] arr = {4, 1, 2, 9, 10, 12, 15}; int len = arr.length; int[] copyArr = new int[len]; for(int i = 0; i < len; i++){ copyArr[i] = arr[i]; } System.out.println(Arrays.toString(copyArr));
打印[4, 1, 2, 9, 10, 12, 15]复制成功
for循环数组扩容
int[] arr = {4, 1, 2, 9, 10, 12, 15}; int len = arr.length; int newLen = 20; int[] copyArr = new int[newLen]; for(int i = 0; i < len; i++){ copyArr[i] = arr[i]; } System.out.println(Arrays.toString(copyArr));
打印[4, 1, 2, 9, 10, 12, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],扩容成功
要是工作中老是遇到复制数组该怎么办呢?很简单,封装个静态方法不就可以了。等等,既然智商如我这么低的人都知道封装方法,那前辈们肯定封装好了,那就找一找呗
Arrays.copyf方法
千辛万苦在Arrays类里找到了此方法,因为Java基本类型不支持泛型,所以此方法对8种基本类型重载,下面列举出int类型和泛型的两个重载方法的代码基本类型
public static int[] copyOf(int[] orginal, int newLength){ int [] copy = new int[newLength]; System.arraycopy(original, 0, copy 4000 , 0, Math.min(original.length, newLength); return copy; }
有意思的是Math.min(original.length, newLength);,会取原始数组长度和newLength的最小值
所以当newLength < original.length时,相当于对原始数组的截取
int[] arr = {4, 1, 2, 9, 10, 12, 15}; int[] copyArr = Arrays.copyOf(arr, 3); System.out.println(Arrays.toString(copyArr)); //[4, 1, 2]
当newLength > original.length时,相当于对原始数组的扩容
int[] arr = {4, 1, 2, 9, 10, 12, 15}; int[] copyArr = Arrays.copyOf(arr, 13); System.out.println(Arrays.toString(copyArr)); //[4, 1, 2, 9, 10, 12, 15, 0, 0, 0, 0, 0, 0]
当newLength == original.length时呢。别问我了,我不知道
泛型
public static <T> T[] copyOf(T[] original, int newLength) { return (T[]) copyOf(original, newLength, original.getClass()); } public static <T,U> T[] copyOf(U[] original, int newLength, Class<? extends T[]> newType) { //判断如果新类型如果是Object[].class则直接构造一个Object[],如果不是,通常反射创建一个数组 //这么做是为了提升效率,也可能是因ArrayList底层是用Object[]做为容器,提高ArrayList内部扩容的效率 @SuppressWarnings("unchecked") T[] copy = ((Object)newType == (Object)Object[].class) ? (T[]) new Object[newLength] : (T[]) Array.newInstance(newType.getComponentType(), newLength); System.arraycopy(original, 0, copy, 0, Math.min(original.length, newLength)); return copy; }
原理介绍完了,使用方式和上面那个基本一样。
Arrays.copyOfRange
Arrays.copyOfRange方法跟Arrays.copyOf方法一样,也有对八种基本类型的重载操作基本类型
以int类型代码作分析public static int[] copyOfRange(int[] original, int from, int to){ int newLength = to - from; if(newLength < 0){ throw new IllegalArugmentException(from + " > " + to); } int[] copy = new int[newLength]; System.arraycopy(original, from, copy, 0, Math.min(original.length - from, newLength)); return copy; }
最不好理解的地方应该在
System.arraycopy(original, from, copy, 0, Math.min(original.length - from, newLength));这里吧
我发现在Java所有的截取操作中都是截头不截尾(包含from,不包含to),那么上述代码的意思就是从原数组的from处复制到copy数组,以0开始,复制Math.min(original.length - from, newLength)个
System.arraycopy
最低层的数组复制就是public static native void arraycopy(Object src, int srcPos, Object dest, int destPos, int length);
这个方法了,一个native方法
具体的用法是从src的srcPos处把length个长度的元素从dest的destPos处复制进dest数组里
我们可以用这个方法来复制数组
int[] arr = {1, 2 ,3 ,4}; int[] copy = new int[arr.length]; System.arraycopy(arr, 0, copy, 0, arr.length); System.out.println(Arrays.toString(copy)); //[1, 2, 3, 4]
模拟ArrayList的add(int index, E e)操作
//模拟ArrayList的内置数组 int[] arr = {1, 2 ,3 ,4}; //模拟ArrayList的内置数组扩容 int[] copy = Arrays.copyOf(arr, arr.length + arr.length >> 1); //模拟ArrayList的size int size = 4; //模拟要插入的索引 int index = 3; //将数组index处整体向后移动一位 System.arraycopy(copy, index, copy, index + 1, size-index); System.out.println(Arrays.toString(copy)); //[1, 2, 3, 4, 4, 0, 0, 0, 0, 0] //设置index处的值 copy[index] = 100; System.out.println(Arrays.toString(copy)); //[1, 2, 3, 100, 4, 0, 0, 0, 0, 0]
其实ArrayList的底层实现大体就像上面那样
相关文章推荐
- Java中数组的使用方法? 初始化,二维数组,数组复制
- java数组复制的简单方法(一)
- Java中数组复制的几种方法
- Java数组复制五种方法
- JAVA基础再回首(二十二)——转换流概述及用法、简化写法FileWriter和 FileReader、字符缓冲流及特殊用法、字节流字符流复制文件方法总结
- 自定义方法copy数组 和 Java类库对数组复制的支持
- JAVA语言的几种数组复制方法
- JAVA中复制数组的五种方法
- java中复制数组的4中方法
- java语言复制数组的四种方法
- java数组遍历——iterator和for方法(精品总结)
- JAVA中复制数组的方法
- Java数组复制的方法和System.arraycopy
- 读取Java文件到byte数组的三种方法(总结)
- (java 必备知识之一) java 数组复制 System方法 arrayCopy 深入解析
- java 数组复制的方法
- Java对象的复制方法总结
- Java中数组常用方法的总结
- Java中数组复制的几种方法
- java语言复制数组的四种方法