java四种拷贝方式及常见的数组操作方法

一、四种拷贝方式

要确定一个方法是浅拷贝还是深拷贝,必须用引用类型的值,所以要用对象定义数组,以下四种方法的代码中都用对象定义了数组以确定拷贝类型

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));
    }
}

猜你喜欢

转载自blog.csdn.net/weixin_43289802/article/details/83152153