1. 程式人生 > >JAVA語言基礎——(四)陣列(拷貝)

JAVA語言基礎——(四)陣列(拷貝)

一、問題解決

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得到的物件都放在堆上

二、一維陣列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));
    }
    
}

三、陣列拷貝呼叫方法

(1)陣列名.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));
    }

}

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

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

}

(4)實現物件的深拷貝:實現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.將奇數放在偶數前面,大小順序不要求

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},找到這兩個數字