一、 数组的拷贝
-
for循环:浅拷贝,不会生成新的对象;
-
System.arraycopy:浅拷贝,不会产生新的对象;
- System.java文件的arraycopy方法代码:
-
该方法将src数组里的元素赋值给dest数组中的元素;
-
Object是Java语言中的根类,可以表示任意数据类型;
-
native为本地方法,该方法底层用C/C++语言来实现,Java直接调用其方法;
-
src:源数组;
srcPos:源数组要复制的起始位置;
dest:目的数组;
desPos:目的数组放置的起始位置;
length:要复制的长度。
-
clone:返回值为Object类型,所以赋值时会发生强转,基本数据类型都可以直接用clone进行拷贝
-
Array.copyOf :浅拷贝,方法返回一个结果为相同数据类型的长度为指定长度的新数组,不仅拷贝原数组中的元素,还会创建新的对象;
Arrys.copyOf底层调用System.arraycopy方法
源码如下:
original:原始数组;
newLength:新长度;
二、java.util.Arrays工具类常用方法
java.util.Arrays工具类包含了常用的数组操作,方便我们日常开发,Arrays类包含了:排序,查找,填充,打印内容等操作。
- 排序:
Arrays.sort(数组名,[起始索引,结束索引]);
按升序进行数组排序,如果指定范围,则排序范围为 [ 起始索引 ,结束索引 ),若起始索引 == 结束索引,则排序范围为空,如果指定下标越界,则会抛出异常。
- 查找:
Arrays.binarySearch(数组名,[起始索引,结束索引],键值);
使用二分法来搜索指定类型的数组,以查找指定的键值,如果指定范围,则在指定索引范围内搜索,若搜索键包含在数组中,则返回其索引,否则返回 -(插入点 - 1),插入点为第一个大于此键的元素索引。
- 判断两数组是否相等:
Arrays.equals(数组名1,数组名2);
判断两数组是否相等,结果为true或false,如果两个数组以相同顺序包含相同的元素,则两个数组相等,若两个数组引用均为null,则认为它们是相等的。
- 填充:
fill(数组名,[起始索引,结束索引],值); //fill方法的返回值为空。
使用指定值填充数组,如果指定范围,则填充从 [ 起始索引 ,结束索引 ),若起始索引 == 结束索引,则填充范围为空。
源代码:
- 打印:
Arrays.toString(数组名);
返回指定数组内容的字符串表示形式,多维数组用deepToString(数组名);
源码:
- Arrays.copyOfRange
Arrays.copyOfRange(数组名,起始索引,结束索引);
复制指定范围的内容:从 [起始索引,结束索引) 结果为相同数据类型的数组。
三、练习题
- 将奇数放在偶数前面(大小顺序不要求)。eg:{1,2,3,4,5,6}
程序代码:
public static void main(String[] args) {
int[] a = {1,2,3,4,5};
int temp;
for (int i = 0;i < a.length;i++) {
for (int j = 0;j < a.length-i-1;j++) {
if (a[j] % 2 == 0) {
temp = a[j];
a[j] = a[j+1];
a[j+1] = temp;
}
}
}
System.out.println(Arrays.toString(a));
}
运行结果:
- 一个有序数组,给定一个key使有两个数组元素的和加起来等于key,找到这两个数字的下标。eg:
{1,2,3,4,5,6} ,key == 7
程序代码:
public static void main(String[] args) {
int[] a = {1, 2, 3, 4, 5, 6};
int key = 7;
System.out.println("有两个数组元素的和等于7");
System.out.println("=========================");
for (int i = 0; i < a.length; i++) {
for (int j = i + 1; j < a.length; j++) {
if (a[i] + a[j] == key) {
System.out.println("第一个元素的下标是: " + i);
System.out.println("第二个元素的下标是: " + j);
System.out.println("=========================");
}
}
}
}
运行结果:
- 一个整形数组,除了两个数字只出现一次外,其他数字都是两次,找到这两个数字。eg:{1,3,1,2,3,4}
程序代码:
public static void main(String[] args) {
int[] a = {1,3,1,2,3,4};
boolean[] flag = new boolean[a.length];
for (int i = 0;i < a.length;i++) {
for (int j = i+1;j < a.length;j++) {
if (a[i] == a[j]) {
System.out.println("a[" + i + "] " + "=" + "a[" + j + "] = " + a[i]);
flag[i] = true;
flag[j] = true;
}
}
}
for (int i = 0;i < flag.length;i++) {
if (flag[i] == false){
System.out.println("数组中只出现一次的数为: " + a[i]);
}
}
}
运行结果:
- 如何排序数组并插入某个元素?
public static void main(String[] args) {
int[] a = {1,3,12,8,30,5,26};
Arrays.sort(a);
Scanner scan = new Scanner(System.in);
System.out.println("请输入要插入的数字: ");
int s = scan.nextInt();
System.out.println("请输入元素插入位置: ");
int s1 = scan.nextInt();
System.out.println("对原数组进行排序: " + Arrays.toString(a)); //排序;
System.out.println("排序并插入元素后的数组: " + Arrays.toString(testInsert(a,s,s1)));
}
//插入元素;
public static int[] testInsert(int[] array,int key,int loc) {
int[] array1 = new int[array.length+1];
if (loc - 1 == 0) {
array1[loc -1] = key;
System.arraycopy(array,0,array1,1,array.length);
}else {
System.arraycopy(array,0,array1,0,loc-1);
array1[loc - 1] = key;
System.arraycopy(array,loc-1,array1,loc,array.length-loc+1);
}
return array1;
}
运行结果:
- 如何搜索数组中的最小值和最大元素?
- 方法1:
程序代码:
public static void main(String[] args) {
int[] a = {12,5,6,8,13,2};
/*int min = Arrays.stream(a).min().getAsInt();
int max = Arrays.stream(a).max().getAsInt();*/
Arrays.sort(a);
System.out.println("数组中最小的元素是: " +a[0]);
System.out.println("数组中最大的元素是: " + a[a.length-1]);
}
运行结果:
- 方法2:
程序代码:
public static void main(String[] args) {
int[] a = {12,5,6,8,13,2};
int min = Arrays.stream(a).min().getAsInt();
int max = Arrays.stream(a).max().getAsInt();
System.out.println("数组中最小的元素是: " + min);
System.out.println("数组中最大的元素是: " + max);
}
运行结果:
- 如何合并两个数组(合并到一个新的数组)?
程序代码:
public static void main(String[] args) {
int[] a = {1,6,13,7,21};
int[] b = {5,11,19,-1};
System.out.println("a数组: " + Arrays.toString(a));
System.out.println("b数组: " + Arrays.toString(b));
System.out.println("合并排序后的数组: " + Arrays.toString(extendRange(a,b)));
}
//合并数组,先定义一个更大的数组,然后再将原数组内容拷贝到新数组中;
public static int[] extendRange(int[] array,int[] brray) {
int[] abrray = new int[array.length + brray.length];
System.arraycopy(array,0,abrray,0,array.length);
System.arraycopy(brray,0,abrray,array.length-1,(brray.length));
Arrays.sort(abrray);
return abrray;
}
运行结果:
- 如何填充数组(一次填充,部分填充)?
程序代码:
public static void main(String[] args) {
int[] a = new int[10];
a[0] = 1;
a[1] = 2;
System.out.println(Arrays.toString(a));
Arrays.fill(a,4,6,66);
System.out.println("部分填充: " + Arrays.toString(a));
Arrays.fill(a,88);
System.out.println("一次填充: " + Arrays.toString(a));
}
运行结果:
- 如何删除数组指定元素?
- 方法1:
程序代码:
public static void main(String[] args) {
String[] s = {"a","b","c","d","e","f","g"};
System.out.println("删除指定元素后将s.length - i个元素左移: ");
System.out.println(Arrays.toString(remove(s, 3)));
}
//删除数组下标为i的数组元素
public static String[] remove(String[] str,int i){
System.arraycopy(str,i+1,str,i,str.length-i-1);
str[str.length-1] = null; //删除索引为3的元素后,将数组最后一个元素置为null;
return str;
}
运行结果:
- 方法2:
程序代码:
public static void main(String[] args) {
String[] s = {"a", "b", "c", "d", "e", "f", "g"};
System.out.println("在原来位置删除指定元素: " );
System.out.println(Arrays.toString(remove1(s, 3)));
}
//在指定位置删除元素后将此位置元素置为null;
public static String[] remove1(String[] str, int i) {
str[i-1] = null;
return str;
}
运行结果:
- 如何从数组中查找常见的元素?
程序代码:
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
System.out.print("请输入要查找的数组元素:");
int key = scan.nextInt();
int[] array = {1, 2, 3, 4, 5, 6, 7};
if (Arrays.binarySearch(array, key) >= 0) {
System.out.println("该元素的下标: " + Arrays.binarySearch(array, key));
} else {
System.out.println("该元素的下标: -1");
}
}
运行结果: