一、介绍
1、在java.lang包下边有一个System类,其中就有arraycopy方法。
2、方法完整签名:
public static void arraycopy(Object src, int srcPos, Object dest, int destPos, int length)
参数:
src:源数组; srcPos:源数组要复制的起始位置; dest:目的数组; destPos:目的数组放置的起始位置; length:复制的长度。
简单描述就是从src的srcPos位置拷贝length长度的数据到dest的destPos位置,如果src和dest是同一个对象的话,则相当于先将数据拷贝到一个临时的数组,然后再覆盖数组中destPos开始的一段数据。
3、例子:
int arr1[] = {0,1,2,3,4,5};
int arr2[] = {0,10,20,30,40,50};
System.arraycopy(arr1,0,arr2,1,2);
结果:arr2 = [0,0,1,30,40,50];
二、使用实例
1、leetcode 189 旋转数组
给定一个数组,将数组中的元素向右移动 k 个位置,其中 k 是非负数。
示例 1:
输入: [1,2,3,4,5,6,7] 和 k = 3
输出: [5,6,7,1,2,3,4]
解释:
向右旋转 1 步: [7,1,2,3,4,5,6]
向右旋转 2 步: [6,7,1,2,3,4,5]
向右旋转 3 步: [5,6,7,1,2,3,4]
代码:
package test;
import java.util.Arrays;
public class Solution {
public static void main(String[] args) {
// TODO Auto-generated method stub
int[] nums = new int[] {1,2,3,4,5,6,7,8};
int k = 100;
int n = nums.length;
k = k % nums.length;
int[] temp = Arrays.copyOfRange(nums, 0, n-k);
System.out.println("temp:"+Arrays.toString(temp));
//输出:temp:[1, 2, 3, 4, 5]
System.arraycopy(nums, n-k, nums, 0, k);
System.out.println("nums1:"+Arrays.toString(nums));
//输出:nums1:[6, 7, 8, 4, 5, 6, 7, 8]
System.arraycopy(temp, 0, nums, k, n-k);
System.out.println("nums2:"+Arrays.toString(nums));
//nums2:[6, 7, 8, 1, 2, 3, 4, 5]
}
}
三、注意事项
使用此方法有个很严重的问题,由于它的复制是浅复制(shallow copy),复制后的数组与原数组中的数据指向同一个位置.
实例如下:
public class Clone2 {
public static void main(String[] args) {
Te[] t1 = new Te[1];
t1[0] = new Te("a");
Te[] t2 = new Te[1];
System.out.println(t1[0]);
//调用
System.arraycopy(t1, 0, t2, 0, 1);
System.out.println(t2[0]);
}
}
class Te{
String name;
Te(String name) {
this.name = name;
}
}
//输出
/*
CloneTest.Te@74a14482
CloneTest.Te@74a14482
*/
从上面的输出可以看出复制后的数组中的元素与原来指向了一个位置,这样子很容易引发严重的问题.一旦我们更改了原来的数据,复制后的数据也会随之改变.
例如:
public class Clone2 {
public static void main(String[] args) {
Te[] t1 = new Te[1];
t1[0] = new Te("a");
Te[] t2 = new Te[1];
System.out.println("t1修改前:"+t1[0]);
//修改t1[0]
t1[0].name = "2";
System.out.println("t1修改后:"+t1[0]);
//调用
System.arraycopy(t1, 0, t2, 0, 1);
System.out.println("t2:"+t2[0]);
}
}
class Te{
String name;
Te(String name) {
this.name = name;
}
@Override
public String toString() {
return "Te{" +
"name='" + name + '\'' +
'}';
}
}
//输出:
/*
t1修改前:Te{name='a'}
t1修改后:Te{name='2'}
t2:Te{name='2'}
*/
对t1[0]进行修改,但是由于t1[0]和t2[0]引用了同一个对象,因此后者也会随之改变,在平时的使用中如果不注意的话会引起相当大的问题。而且由于System.arraycoppy()是JDK中的native方法,JDK中有关于集合,数组操作的基本上都调用此方法,因此在使用这些的时候要注意。