一、四种拷贝方式
要确定一个方法是浅拷贝还是深拷贝,必须用引用类型的值,所以要用对象定义数组,以下四种方法的代码中都用对象定义了数组以确定拷贝类型
1.for循环拷贝
class TestArray {
private int val = 10;
public void setVal(int val) {
this.val = val;
}
public int getVal() {
return this.val;
}
}
public class TestDemo {
public static void main3(String[] args) {
TestArray[] t1 = new TestArray[4];
t1[0] = new TestArray();
t1[1] = new TestArray();
t1[2] = new TestArray();
t1[3] = new TestArray();
TestArray[] t2 = new TestArray[4];//t2[0]
for(int i = 0;i < t1.length;i++) {
t2[i] = t1[i];
}
for(int i = 0;i < t1.length;i++) {
System.out.print(t1[i].getVal()+" ");
}
System.out.println();
for(int i = 0;i < t2.length;i++) {
System.out.print(t2[i].getVal()+" ");
}
System.out.println();
t2[0].setVal(100000);
System.out.println("===============");
for(int i = 0;i < t1.length;i++) {
System.out.print(t1[i].getVal()+" ");
}
System.out.println();
for(int i = 0;i < t2.length;i++) {
System.out.print(t2[i].getVal()+" ");
}
}
}
输出结果:
由输出结果可以看出在改变数组第一个元素的情况下,由对象定义的数组中元素也改变了,所以for循环的拷贝方式为浅拷贝
2.clone()方法
class TestArray {
private int val = 10;
public void setVal(int val) {
this.val = val;
}
public int getVal() {
return this.val;
}
}
public class TestDemo {
public static void main(String[] args) {
TestArray[] t1 = new TestArray[4];
t1[0] = new TestArray();
t1[1] = new TestArray();
t1[2] = new TestArray();
t1[3] = new TestArray();
TestArray[] t2 = t1.clone();
for(int i = 0;i < t1.length;i++) {
System.out.print(t1[i].getVal()+" ");
}
System.out.println();
for(int i = 0;i < t2.length;i++) {
System.out.print(t2[i].getVal()+" ");
}
System.out.println();
t2[0].setVal(100000);
System.out.println("===============");
for(int i = 0;i < t1.length;i++) {
System.out.print(t1[i].getVal()+" ");
}
System.out.println();
for(int i = 0;i < t2.length;i++) {
System.out.print(t2[i].getVal()+" ");
}
}
}
由输出结果可以看出在改变数组第一个元素的情况下,由对象定义的数组中元素也改变了,所以clone()的拷贝方式为浅拷贝
此方法会产生新的对象
3.System.arraycopy方法
此方法是浅拷贝,不会产生新的对象
class TestArray {
private int val = 10;
public void setVal(int val) {
this.val = val;
}
public int getVal() {
return this.val;
}
}
public class TestDemo {
public static void main11(String[] args) {
TestArray[] t1 = new TestArray[4];
t1[0] = new TestArray();
t1[1] = new TestArray();
t1[2] = new TestArray();
t1[3] = new TestArray();
TestArray[] t2 = new TestArray[4];
System.arraycopy(t1,0,t2,0,t1.length);
for(int i = 0;i < t1.length;i++) {
System.out.print(t1[i].getVal()+" ");
}
System.out.println();
for(int i = 0;i < t2.length;i++) {
System.out.print(t2[i].getVal()+" ");
}
System.out.println();
t2[0].setVal(100000);
System.out.println("===============");
for(int i = 0;i < t1.length;i++) {
System.out.print(t1[i].getVal()+" ");
}
System.out.println();
for(int i = 0;i < t2.length;i++) {
System.out.print(t2[i].getVal()+" ");
}
}
}
//System.arraycopy()方法java源代码中的代码
public static native void arraycopy(Object src, int srcPos,
Object dest, int destPos,
int length);
native :调用的是本地方法,此方法执行速度非常快
src :源地址
srcPos:源地址开始位置
dest:目的地
destPos:目的地的开始位置
length:拷贝的长度
4.Arrays.copyOf()方法
此方法为浅拷贝,此方法底层调用的还是System.arraycopy()方法。
此方法会产生新的对象
class TestArray {
private int val = 10;
public void setVal(int val) {
this.val = val;
}
public int getVal() {
return this.val;
}
}
public class TestDemo {
public static void main(String[] args) {
TestArray[] t1 = new TestArray[4];
t1[0] = new TestArray();
t1[1] = new TestArray();
t1[2] = new TestArray();
t1[3] = new TestArray();
TestArray[] t2 = Arrays.copyOf(t1,t1.length);
for(int i = 0;i < t1.length;i++) {
System.out.print(t1[i].getVal()+" ");
}
System.out.println();
for(int i = 0;i < t2.length;i++) {
System.out.print(t2[i].getVal()+" ");
}
System.out.println();
t2[0].setVal(100000);
System.out.println("===============");
for(int i = 0;i < t1.length;i++) {
System.out.print(t1[i].getVal()+" ");
}
System.out.println();
for(int i = 0;i < t2.length;i++) {
System.out.print(t2[i].getVal()+" ");
}
}
}
此方法使用时共有两个参数,第一个为源数组,第二个为要拷贝的数组长度
二、常用数组操作方法
1.如何填充数组(一次填充,部分填充)
public class TestDemo3 {
public static void main(String[] args) {
int[] array = new int[10];
Arrays.fill(array, 15);
System.out.println(Arrays.toString(array));
int[] brray = new int[10];
Arrays.fill(brray, 0, 5, 15);
System.out.println(Arrays.toString(brray));
}
}
结果如下:
2.搜索数组中的最小值和最大元素
将一个数组放入stream中,直接调用stream中的min和max方法求值
public class TestDemo3 {
public static void main(String[] args) {
int[] array = {1,5,8,2,1,5,6};
int min = Arrays.stream(array).min().getAsInt();
System.out.println(min);
int max = Arrays.stream(array).max().getAsInt();
System.out.println(max);
}
}
3.如何合并两个数组(合并到一个新的数组)
public class TestDemo3 {
public static void main(String[] args) {
int[] array1 = {1,2,3,4,5};
int[] array2 = {6,7,8,9,10};
int[] array3 = new int[array1.length+array2.length];
System.arraycopy(array1,0,array3,0,array1.length);
System.arraycopy(array2,0,array3,array1.length,array2.length);
System.out.println(Arrays.toString(array3));
}
}
4.如何从数组中查找常见的元素
public class TestDemo3 {
public static void main(String[] args) {
int[] array = {1, 2, 3, 4, 5, 6, 7};
System.out.println(Arrays.binarySearch(array,4));
}
}
//找到返回key的下标,没找到返回-1
5.如何删除数组指定元素
public class TestDemo3 {
public static void main(String[] args) {
int[] array = {1, 2, 3, 4, 5, 6, 7};
for (int i = 0; i < array.length; i++) {
System.out.println(i + "号下标" + "指向数字: " + array[i]);
}
Scanner in = new Scanner(System.in);
System.out.println("输入要删除的数的下标:");
int del = in.nextInt();
for (int i = del; i < array.length - 1; i++) {
array[i] = array[i + 1];//将要删除的下标后的值全部前移一位,即覆盖所要删除的数
}
int[] brray = Arrays.copyOf(array, array.length - 1);
System.out.println(Arrays.toString(brray));
}
}
6.如何排序数组并插入某个元素
public class TestDemo3 {
public static void main(String[] args) {
int[] array = {1, 2, 3, 4, 5, 6, 7};
Arrays.sort(array);//对数组排序
for (int i = 0; i < array.length; i++) {
System.out.println(i + "号下标" + "指向数字: " + array[i]);
}
int[] brray = Arrays.copyOf(array, array.length + 1);
Scanner in = new Scanner(System.in);
System.out.println("输入要加的数的下标:");
int add = in.nextInt();
for (int i = brray.length - 1; i >= add; i--) {
brray[i] = brray[i - 1];//将所要加的数的坐标上原本的数以及之后的数依次向后移动一位
}
System.out.println("输入要加的数:");
int addsum = in.nextInt();
brray[add] = addsum;
System.out.println(Arrays.toString(brray));
}
}
例题:
1.给定一个数组,将数组中奇数放在偶数之前
public class TestDemo2 {
public static void handle(int[] array) {
int i = 0;
int j = array.length - 1;
while (i < j) {//i从数组第一个元素开始,j从数组最后元素开始,当两者相遇时,跳出循环
if (array[i] % 2 == 1) {//如果i是奇数,继续对下个元素进行判断
i++;
} else if (array[j] % 2 == 1) {//如果i是奇数,j是偶数,将两者进行交换
int tmp = array[i];
array[i] = array[j];
array[j] = tmp;
i++;
j--;//两者分别从下一地方开始
} else {//i是奇数,j是奇数,j继续递减,直到出现偶数
j--;
}
}
System.out.println(Arrays.toString(array));
}
public static void main(String[] args) {
int[] array = {1, 2, 3, 5, 8};
handle(array);
}
}
2.一个数组是有序的,给定一个key:数字, 数组中有两个数字的和加起来等于key,输出这两个数
public class TestDemo2 {
public static void search(int[] array, int key) {
int i = 0;
int j = array.length - 1;//数组有序,所以可以从两个方向进行查找
while (i < j) {//当i,j相遇时跳出循环
if (key == array[i] + array[j]) {
System.out.println(array[i] + "+" + array[j] + "=" + key);
i++;//如果当前两元素之和等于key,输出,并将i递加,j递减,求数组中还有没有其他元素符合要求
j--;
} else if (array[i] + array[j] < key) {
i++;//如果当前和小于key,因为数组有序,则肯定是i值小了,所以将i向后移动
} else {
j--;//如果当前和大于key,因为数组有序,则肯定是j值大了,所以将j向前移动
}
}
if (i <= j) {//跳出循环的条件,说明数组中不存在两数之和等于输入的数
System.out.println("没有两项的和等于" + key);
}
}
public static void main(String[] args) {
int[] array = {1, 2, 3, 5, 8};
search(array, 9);
}
}
3.输出一个数组中只出现了一次的数
public class TestDemo5 {
public static int searchOne(int number) {
int count = 0;
while ((number & 1) == 0 && count < 32) {
number = number >>> 1;
count++;
}
return count;
}
public static boolean isOne(int number, int index) {
number = number >>> index;
if ((number & 1) == 0) {
return false;
}
return true;
}
public static int[] findNum(int[] array) {
int result = 0;
for (int i = 0; i < array.length; i++) {
result ^= array[i];
}
int index = searchOne(result);
int num1 = 0;
int num2 = 0;
for (int i = 0; i < array.length; i++) {
if (isOne(array[i], index)) {
num1 ^= array[i];
} else {
num2 ^= array[i];
}
}
int[] resultArray = {0, 0};
resultArray[0] = num1;
resultArray[1] = num2;
return resultArray;
}
public static void main(String[] args) {
int[] array = {1, 2, 3, 3, 2, 5};
int[] result = findNum(array);
System.out.println(Arrays.toString(result));
}
}