JAVA语言基础(四)——数组(拷贝)

一、数组拷贝调用方法

(1)一维数组for循环拷贝

package demo;

import java.util.Arrays;

class TestArray{
    private int val = 3;
    public void setVal(int val){
        this.val = val;//this引用类的当前实例,只能在构造方法、实力初始化代码块和实例方法中使用,直接访问实例字段。静态成员方法中不能使用this关键字。
    }
    public int getVal(int Val){
        return this.val;
    }
}

public class Test1017_for {
    public static void main(String[] args){

        TestArray[] t1 = new TestArray[4];//创建长度为4的数组t1
        t1[0] = new TestArray();
        t1[1] = new TestArray();
        t1[2] = new TestArray();
        t1[3] = new TestArray();

        TestArray[] t2 = new TestArray[4];
        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(1) + " ");
        }
        System.out.println();
        for(int i = 0;i < t2.length;i ++) {
            System.out.print(t2[i].getVal(1) + " ");
        }

        System.out.println();

        t2[0].setVal(10000);//更改t2[0]的值看t1有没有变化,运行后t1也改变,for循环是浅拷贝
        System.out.println("===========");
        for(int i = 0;i < t1.length;i ++){
            System.out.print(t1[i].getVal(1) + " ");
        }

        System.out.println();

        for(int i = 0;i < t2.length;i ++) {
            System.out.print(t2[i].getVal(1) + " ");
        }

//        //for循环数组
//        int[] a_array = {1,2,3,4,5,6,7,8,9};
//        int[] b_array = new int[a_array.length];
//        for(int i = 0;i < a_array.length;i ++){
//            b_array[i] = a_array[i];
//        }
//        System.out.println(Arrays.toString(a_array));
//        System.out.println(Arrays.toString(b_array));
//        b_array[0] = 10000;
//        System.out.println("===========");
//        System.out.println(Arrays.toString(a_array));
//        System.out.println(Arrays.toString(b_array));
    }
    
}

(2)数组名.clone()——浅拷贝

package demo;

import java.util.Arrays;

class TestArray1{
    private int val = 2;
    public void setVal(int val){
        this.val = val;
    }
    public int getVal(int val){
        return this.val;
    }
}

public class Test1017_array_clone {
    public static void main(String[] args) {
        TestArray1[] t1 = new TestArray1[4];
        t1[0] = new TestArray1();
        t1[1] = new TestArray1();
        t1[2] = new TestArray1();
        t1[3] = new TestArray1();
        TestArray1[] t2 = t1.clone();

        for(int i = 0;i < t1.length;i ++){
            System.out.print(t1[i].getVal(1) + " ");
        }
        System.out.println();
        for(int i = 0;i < t1.length;i ++){
            System.out.print(t2[i].getVal(1) + " ");
        }
        System.out.println();
        t2[0].setVal(10000);
        System.out.println("==================");

        for(int i = 0;i < t1.length;i ++){
            System.out.print(t1[i].getVal(1) + " ");
        }
        System.out.println();
        for(int i = 0;i < t1.length;i ++){
            System.out.print(t2[i].getVal(1) + " ");
        }

//        int[] a = {1,2,3,4,5,6,7,8,9};
//        int[] b = a.clone();
//        System.out.println(Arrays.toString(a));
//        System.out.println(Arrays.toString(b));
//        b[0] = 10000;
//        System.out.println("================");
//        System.out.println(Arrays.toString(a));
//        System.out.println(Arrays.toString(b));
    }

}

(3)System.arraycopy()——浅拷贝

1.是一个本地的方法,源码中定义如下:

public static native void arraycopy(Object src,  int  srcPos,
                                        Object dest, int destPos,
                                        int length);

2.当使用这个方法时,复制到的数组是已经分配内存单元的。

package demo;

import java.util.Arrays;

class TestArray2{
    private int val = 2;
    public void setVal(int val){
        this.val = val;
    }
    public int getVal(int val){
        return this.val;
    }
}

public class Test1017_System_arraycopy {
    public static void main(String[] args) {
        TestArray2[] t1 = new TestArray2[5];
        t1[0] = new TestArray2();
        t1[1] = new TestArray2();
        t1[2] = new TestArray2();
        t1[3] = new TestArray2();
        t1[4] = new TestArray2();
        TestArray2[] t2 = new TestArray2[t1.length];
        System.arraycopy(t1,0,t2,0,t1.length);

        for(int i = 0;i < t1.length;i ++){
            System.out.print(t1[i].getVal(1) + " ");
        }
        System.out.println();
        for(int i = 0;i < t1.length;i ++){
            System.out.print(t2[i].getVal(1) + " ");
        }
        System.out.println();
        t2[0].setVal(10000);
        System.out.println("==================");

        for(int i = 0;i < t1.length;i ++){
            System.out.print(t1[i].getVal(1) + " ");
        }
        System.out.println();
        for(int i = 0;i < t1.length;i ++){
            System.out.print(t2[i].getVal(1) + " ");
        }

//        int[] a = {1,2,3,4,5};
//        int[] b = new int[a.length];
//        System.arraycopy(a,0,b,0,a.length);
//        System.out.println(Arrays.toString(a));
//        System.out.println(Arrays.toString(b));
    }
}

(4)Array.copyOf()——浅拷贝

底层调用System.arraycopy()

package demo;

import java.util.Arrays;

class TestArray3{
    private int val = 2;
    public void setVal(int val){
        this.val = val;
    }
    public int getVal(int val){
        return this.val;
    }
}

public class Test1017_Arrays_copyOf {
    public static void main(String[] args) {
        TestArray3[] t1 = new TestArray3[5];
        t1[0] = new TestArray3();
        t1[1] = new TestArray3();
        t1[2] = new TestArray3();
        t1[3] = new TestArray3();
        t1[4] = new TestArray3();
        TestArray3[] t2 = new TestArray3[t1.length];
        System.arraycopy(t1,0,t2,0,t1.length);

        for(int i = 0;i < t1.length;i ++){
            System.out.print(t1[i].getVal(1) + " ");
        }
        System.out.println();
        for(int i = 0;i < t1.length;i ++){
            System.out.print(t2[i].getVal(1) + " ");
        }
        System.out.println();
        t2[0].setVal(10000);
        System.out.println("==================");

        for(int i = 0;i < t1.length;i ++){
            System.out.print(t1[i].getVal(1) + " ");
        }
        System.out.println();
        for(int i = 0;i < t1.length;i ++){
            System.out.print(t2[i].getVal(1) + " ");
        }

//        int[] a = {2,1,4,3};
//        int[] b = Arrays.copyOf(a,a.length);
//        System.out.println(Arrays.toString(a));
//        System.out.println(Arrays.toString(b));
    }

}

实现对象的深拷贝:

实现Cloneable接口,并重写clone方法。一个类不实现这个接口直接使用clone方法是编译通不过的。

二、匿名数组

顾名思义,匿名数组就是没有名字的数组

package demo;

import java.util.Arrays;

public class Test1017_AnonymousArray {
    //可变参数编程(数组)
    public static int sum(int... array){//语法
        int sum = 0;
        for(int i : array){
            sum = sum + i;
        }
        return sum;
    }

    public static int sum1(int[] a){
        int sum = 0;
        for(int i : a){
            sum = sum + i;
        }
        return sum;
    }

    public static void main(String[] args) {
        int[] a = {1,2,3,4,};
        System.out.println(sum(a));

        System.out.println(sum(1,2));

        System.out.println(sum1(a));

        /*
        int[] array = {1,2,3,4,5};//创建数组对象时就给数组赋值,没有使用new关键字
        System.out.println(Arrays.toString(array));//输出:[1, 2, 3, 4, 5]

        int[] a = new int[]{1,2,3,4};//创建一个新的数组,根据花括号里面的值对数组进行初始化,数组的长度就是花括号里数据的个数
        System.out.println(Arrays.toString(a));//输出:[1, 2, 3, 4]

        //在不创建新数组的情况下,重新去初始化一个数组
        array = new int[]{5,6,7,8,9};
        System.out.println(Arrays.toString(array));//输出:[5, 6, 7, 8, 9]
        */
    }
}

三、问题解决

1.二分查找

(1)int mid = (low + high)>>>1;//mid = (low + high) / 2位运算最快
(2)return -(low + 1);//查找失败,返回-(如果存在这个数将会在哪里)
(3)无须数组:先排序后查找
调用方法:Arrays.sort()

        int[] array = {3,6,2,1,5};
        Arrays.sort(array);//优化后的快速排序

(4)二分查找调用方法Arrays.binarySearch()
2.求连续子数组的最大和
两个嵌套for循环时间复杂度为O(n^2)

int max = Integer.MIN_VALUE;//0x8000 0000
        int sum = 0;
        for(int i = 0;i < array.length;i ++){
            if (sum <= 0){
                sum = array[i];
            }else{
                sum = sum + array[i];
            }
            if(sum > max){
                max = sum;
            }
        }
        return max;

注:所有new得到的对象都放在堆上

四、练习

1.将奇数放在偶数前面,大小顺序不要求

package demo;

import java.util.Arrays;
//将奇数放在偶数前面     大小顺序不要求
public class Demo1019_OddInFrontOfEve {
    public static int[] front(int[] array) {
        int i = 0;
        int j = array.length - 1;//设两个标记,i在数组开始,j在数组最后
        while(i< j) {//当i不小于j时,数组遍历结束
            while(i < j && array[i] % 2 != 0) {//如果a[i]是奇数,i++,判断下一个数;如果是偶数,需要交换
                i ++;
            }
            while(i < j && array[j] % 2 == 0) {//如果a[i]是偶数,j--,判断前一个数;如果是奇数,需要交换
                j --;
            }
            if(i < j){//交换偶数和奇数的位置
                int t = array[i];
                array[i] = array[j];
                array[j] = t;
            }
        }
        return array;
    }

    public static void main(String[] args) {
        int[] array = {1,2,3,4,5,6,7};
        System.out.println(Arrays.toString(front(array)));
    }
}

2.一个数组是有序的,给定一个key:数字,有两个数字的和加起来等于key,找到这两个数字的下标,时间复杂度O(n)

package demo;

import java.util.Arrays;
//一个数组是有序的,给定一个key:数字,有两个数字的和加起来等于key,找到这两个数字的下标,时间复杂度O(n)
public class Demo1019_SumKey {
    public static int[] sumKey(int[] array,int key) {
        int[] result = new int[2];
        int i = 0;
        int j = array.length - 1;
        int sum = 0;
        while(i < j) {
            sum = array[i] + array[j];
            if(sum < key){
                i ++;
            }else if(sum > key){
                j --;
            }else{
                result[0] = i;
                result[1] = j;
                break;
            }
        }
        return result;
    }

    public static void main(String[] args) {
        int[] array = {0,1,2,3,4,5};
        System.out.println(Arrays.toString(sumKey(array,6)));
    }
}

3.在一个数组的指定位置插入某个元素

package demo;

import java.util.Arrays;
//在一个数组的指定位置插入某个元素
public class Demo1019_Insert {
    public static int[] insert(int[] array,int key,int index){
        int[] array_1 = new int[array.length + 1];//创建一个长度为array.length+1的数组用于存放插入一个元素之后的数组
        System.arraycopy(array,0,array_1,0,index);//把要插入位置之前的index个元素复制到新的数组中
        array_1[index] = key;//将一个元素插入到该位置
        System.arraycopy(array,index,array_1,index + 1,array.length - index);//将插入位置后面的array.length - index个元素复制到array_1[index]后
        return array_1;
    }

    public static void main(String[] args) {
        int[] array = {2,2,2,2,2,2};
        System.out.println(Arrays.toString(insert(array,100,2)));
    }
}

4.搜索数组中的最小值和最大元素

package demo;

import java.util.Arrays;

//搜索数组中的最小值和最大元素
public class Demo1019_SearchMinAndMax {
    public static int[] minAndMax(int[] array){
        //查找开始之前,最小值和最大值都是a[0]
        int min = array[0];
        int max = array[0];
        int[] result = new int[2];//创建一个长度为2的数组存放找到的最小值和最大值
        for(int i = 0;i < array.length;i ++){
            if(array[i] < min){//当a[i]比之前的min小,将a[i]赋给min
                min = array[i];
            }else if(array[i] > max){//当a[i]比之前的max大,将a[i]赋给max
                max = array[i];
            }
        }
        //将查找结果放入结果数组内并返回结果数组
        result[0] = min;
        result[1] = max;
        return result;
    }

    public static void main(String[] args) {
        int[] array = {3,2,-4,6,1,4};
        System.out.println(Arrays.toString(minAndMax(array)));
    }
}

5.合并两个数组(合并到一个新的数组)

package demo;

import java.util.Arrays;
//合并两个数组(合并到一个新的数组)
public class Demo1019_ConnectArrays {
    public static int[] connect(int[] array_a,int[] array_b){
        int[] array_c = new int[array_a.length + array_b.length];//合并后的数组长度等于两个被合并数组长度之和
        System.arraycopy(array_a,0,array_c,0,array_a.length);//将第一个数组复制在目的数组内
        System.arraycopy(array_b,0,array_c,array_a.length,array_b.length);//将第二个数组复制并跟在第一个数组后面
        return array_c;
    }

    public static void main(String[] args) {
        int[] array = {1,2,3,4,5,6,7};
        int[] array1 = {11,22,33,44};
        int[] array_2 = connect(array,array1);
        System.out.println(Arrays.toString(array_2));
    }
}

6.填充数组(一次填充,部分填充)

package demo;

import java.util.Arrays;

//填充数组(一次填充,部分填充)
public class Demo1019_FillArray {
    public static int[] fillingOnce(int[] array,int key){//一次填充
        Arrays.fill(array,key);//将数组所有元素填充为key
        return array;
    }

    public static void main(String[] args) {
        int[] array = new int[10];
        array[3] = 8;
        array[5] = 8;
        array[6] = 8;
        System.out.println(Arrays.toString(array));
        System.out.println(Arrays.toString(fillingOnce(array,11111)));

        Arrays.fill(array,2,7,5);//将数组array下标为[2,5)的元素填充为5
        System.out.println(Arrays.toString(array));
    }
}

7.删除数组指定元素

package demo;

import java.util.Arrays;

//删除数组指定元素
public class Demo1019_Delete {
    public static int[] delete(int[] array,int index){
        for(int i = index;i < array.length - 1;i ++){//将下标为index的元素之后的元素都被它的后一个元素覆盖掉
            array[i] = array[i + 1];
        }
        array[array.length - 1] = 0;//将最后一个元素赋为0
        return array;
    }

    public static void main(String[] args) {
        int[] array = {1,3,5,2,4,6};
        System.out.println(Arrays.toString(delete(array,2)));
    }
}

8.如何从数组中查找常见的元素

package demo;

import java.util.Arrays;

//如何从数组中查找常见的元素
public class Demo1019_SearchCommonElement {
    public static int commen(int[] array,int key){
        int index = Arrays.binarySearch(array,key);//在该数组内二分查找所找的元素
        if(index >= 0){//该元素存在,返回下标
            return index;
        }
        return -1;//该元素不存在,返回-1
    }

    public static void main(String[] args) {
        int[] array = {1,2,3,4,5,6,3};
        System.out.println(commen(array,3));
    }
}

9.一个整型数组,除了两个数字只出现一次外,其他数字都是两次。{1,3,1,2,3,4},找到这两个数字

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值