程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> JAVA編程入門知識 >> 關於JAVA 數組的使用介紹

關於JAVA 數組的使用介紹

編輯:JAVA編程入門知識

JAVA數組與容器類主要有三方面的區別:效率、類型和保存基本類型的能力。在JAVA中,數組是一種效率最高的存儲和隨機訪問對象引用序列的方式。數組就是一個簡單的線性數列,這使得元素訪問非常快速。但是為此付出的代價卻是數組的大小被固定,並且在其生命周期中不可改變。

由於范型和自動包裝機制的出現,容器已經可以與數組幾乎一樣方便地用於基本類型中了。數組和容器都可以一定程度上防止你濫用他們,如果越界,就會得到RuntimeException異常。數組碩果僅存的優勢便是效率,然而,如果要解決更一般化的問題,那數組可能會受到過多的限制,因此這種情況下大部分還是會選擇容器。

因此,如果使用最近的JAVA版本,應該優先選擇容器而不是數組。只有在已證明性能已成為問題,並且切換到數組可以提高性能時,才應該重構程序為數組。

【初始化】
JAVA對數組初始化有很嚴格的規定,這樣可以有效地防止濫用數組。如果初始化錯誤,會直接得到CompileException而不是RuntimeException。在未對數組正確初始化之前,無法用此數組引用做任何事情。
數組定義有int[] array 和int array[],一般采用第一種風格,可以將類型與變量名分開。
數組的初始化有兩種方式,靜態初始化和動態初始化。初始化的時候必須指定長度,多維數組第一維的長度必須指出,同時必須由高維向低維定義。初始化動作可以在代碼的任何地方,而用{}方式只能在創建數組的地方出現。具體初始化方式見程序:
代碼如下:

public class javaArrayInit{
    public static void main(String args[]){
        int[] arrayA; //未初始化
        int[] arrayB = new int[5]; //靜態初始化
        //System.out.println(arrayA.length);  //CompileException
        System.out.println("arrayB length: " + arrayB.length); //無法得到實際保存的元素個數

        arrayA = new int[10]; //動態初始化
        System.out.println("arrayA length: " + arrayA.length);

        int[] arrayC = new int[]{1,2,3,4};
        System.out.println("arrayC length: " + arrayC.length);

        //int[] arrayD = new int[1]{1}; //錯誤的初始化,不能同時定義維和初始化值

        int[][] arrayE = new int[1][];
        System.out.println("arrayE length: " + arrayE.length);

        //int[][] arrayF = new int[][2]; //應先指定高維的長度

        int[][] arrayG = new int[][]{{1,2,3,4},{5,6,7},{7,24,23,24}};
        System.out.println("arrayG length: " + arrayG.length);

        int[][][] arrayH = new int[][][]{{{1,2,3},{4,5,6},{7,8,9},{10,11,12}}};
        System.out.println("arrayH length: " + arrayH.length);

        dummyArray[] arrayI = {new dummyArray(),new dummyArray()}; //自定義數組類型
        System.out.println("arrayI length: " + arrayI.length);
        System.out.println("arrayI[1]: " + arrayI[1].getValue());

        dummyArray[] arrayK = new dummyArray[5];
        System.out.println("arrayK[0]: " + arrayK[0]); //null
        for(int i = 0; i < arrayK.length; i++){
            arrayK[i] = new dummyArray();
        }
        System.out.println("arrayK[0]: " + arrayK[0].getValue()); //2
    }
}
class dummyArray{
    private static int temp;
    private final int arrayValue = temp++;
    public int getValue(){
        return arrayValue;
    }
}

輸出:

arrayB length: 5
arrayA length: 10
arrayC length: 4
arrayE length: 1
arrayG length: 3
arrayH length: 1
arrayI length: 2
arrayI[1]: 1
arrayK[0]: null
arrayK[0]: 2

【length】
只讀成員length是數組對象的一部分(雖然實際上API裡面並沒有聲明這個變量,是運行時動態生成),這是唯一一個可以訪問的字段或方法。而[]語法是訪問數組對象的唯一方式,容器是通過get()方法訪問。可以使用Array.length來得到數組的大小,注意與String類型的String.length()區分。Array使用的是成員變量的方式,而String使用的是成員方法的方式。同時,Array.length只能得到數組的大小,而無法得到數組實際有多少元素。多維數組的length只計算第一維的長度。
代碼如下:

public class javaArrayLength{
    public static void main(String args[]){
        int[] arrayA = new int[15];
        arrayA[1] = 1;
        arrayA[2] = 2;
        arrayA[3] = 3;
        System.out.println("arrayA length: " + arrayA.length);

        int[][] arrayB = new int[10][];
        System.out.println("arrayB length: " + arrayB.length);

        int[][] arrayC = new int[][]{{1,1,1,2,},{1,1,2,3,4,5},{4,5,6,7,7},};//注意後面的逗號
        System.out.println("arrayC length: " + arrayC.length);

        int[][] arrayD = new int[][]{{1,1,1,2,},{1,1,2,3,4,5},{4,5,6,7,7},{}};
        System.out.println("arrayD length: " + arrayD.length);
    }
}
輸出:

arrayA length: 15
arrayB length: 10
arrayC length: 3
arrayD length: 4

【Arrays.fill】
Arrays.fill是一個作用十分有限的方法,因為它只能用同一個值填充各個位置(如果是對象,則復制同一個引用進行填充)。使用Arrays.fill可以填充整個數組或者數組的某一個區域,但是由於只能用單一的數值來調用Arrays.fill,因此作用並不是很大。

【賦值與引用】
JAVA數組初始化的時候擁有的只是對數組的引用,並沒有給數組分配存儲空間。因此,數組之間的復制不能簡單地用“=”賦值,因為操作的是同一對象。如下程序:
代碼如下:

public class javaArrayQuote{
    public static void main(String args[]){
        String testA = "testA";
        String testB = "testB";
        String[] arrayA = new String[]{"arrayA"};
        String[] arrayB = new String[]{"arrayB"};
        testB = testA;
        testB = "testB change";
        System.out.println("I'm testA,I have no changed: " + testA);
        arrayB = arrayA;
        arrayB[0] = "arrayB have changed";
        System.out.println("I'm arrayA, I have no changed: " + arrayA[0]);

    }
}
輸出:

I'm testA,I have no changed:testA
I'm arrayA, I have no changed:arrayB have changed

可以看出,我們改變arrayB[0]的值,改變的是引用的數組,因此我們輸出arrayA[0],其實和arrayB[0]一樣。

【數組復制】
        JAVA中復制數組的方法:

        1.使用FOR循環復制全部或指定元素,效率較低
        2.使用clone方法,得到數組的值,而不是引用。然而clone不能復制指定元素,靈活性較低
        3.使用System.arraycopy(src, srcPos, dest, destPos, length)方法,java標准類庫提供有static方法 System.arraycopy(),用它復制數組要比for循環快很多,System.arraycopy()針對所有類型做了重載,基本類型數組和對象數組都可以用System.arraycopy()復制,但是對象數組只是復制引用,不會出現兩份對象的拷貝。這被稱作淺復制(shallowcopy)。
               src:源數組;
                srcPos:源數組要復制的起始位置;
                dest:目的數組;
                destPos:目的數組放置的起始位置;
                length:復制的長度.
        注意:System.arraycopy()不會進行自動包裝和自動拆包,因此兩個數組必須是同類型或者可以轉換為同類型的數組。同時,這個方法也可以用於復制數組本身。
        int[] test ={0,1,2,3,4,5,6};
        System.arraycopy(test,0,test,3,3);
        則結果為:{0,1,2,0,1,2,6};
        測試程序如下:
代碼如下:

public class javaArrayCopy{
    public static void main(String args[]){
        int[] array = {1,2,3,4,5,6,7,8,9};
        //for循環方法
        int[] arrayA = new int[9];
        for(int i = 0; i < arrayA.length; i++){
            arrayA[i] = array[i];
            System.out.print(arrayA[i] + ",");
        }
        //測試
        System.out.println("");
        arrayA[1] = 19;
        for(int i = 0; i < arrayA.length; i++){
            System.out.print(arrayA[i] + ",");
        }
        System.out.println("");
        for(int i = 0; i < array.length; i++){
            System.out.print(array[i] + ",");
        }
        System.out.println("");

        //clone方法
        int[] arrayB = new int[9];
        arrayB = array.clone();
        //測試
        arrayB[1] = 19;
        for(int i = 0; i < arrayB.length; i++){
            System.out.print(arrayB[i] + ",");
        }
        System.out.println("");
        for(int i = 0; i < array.length; i++){
            System.out.print(array[i] + ",");
        }
        System.out.println("");

        //System.arrayCopy 方法
        int[] arrayC = new int[9];
        System.arraycopy(array, 0, arrayC, 0, arrayC.length);
        //測試
        arrayC[1] = 19;
        for(int i = 0; i < arrayC.length; i++){
            System.out.print(arrayC[i] + ",");
        }
        System.out.println("");
        for(int i = 0; i < array.length; i++){
            System.out.print(array[i] + ",");
        }
    }
}

【數組比較】
Arrays提供了重載後的equals()方法,針對所有類型和Object類型都做了重載,用來比較整個數組。數組相等的條件是元素個數必須相等,並且對應位置的元素也相等。而多維數組的比較用deepEquals()方法。Array.equals()方法比較的兩個數組必須是同類型的數組。
代碼如下:

import java.util.Arrays;
public class javaArrayEquals{
    public static void main(String args[]){
        int[] arrayA = {1,2,3};
        int[] arrayB = {1,2,3,};
        int[] arrayC = new int[4]; //if int[] arrayC = new int[3],return true
        arrayC[0] = 1;
        arrayC[1] = 2;
        arrayC[2] = 3;
        System.out.println(Arrays.equals(arrayA, arrayB));
        System.out.println(Arrays.equals(arrayA, arrayC));

        String[][] arrayD = {{"a","b"},{"c","d"}};
        String[][] arrayE = {{"a","b"},{"c","d"}};
        System.out.println(Arrays.deepEquals(arrayD, arrayE));
    }
}

【數組排序與查找】
數組提供了內置的排序方法sort(),可以對任意基本類型數組或者對象數組進行排序(該對象必須實現Comparable接口或者具有相關聯的Comparator)。JAVA對不同的類型提供了不同的排序方法----針對基本類型設計的快速排序,以及針對對象設計的“穩定歸並排序”,所以無需擔心數組排序的效率問題。
 binarySearch()用於在以排好序的數組中快速查找元素,如果對未排序的數組使用binarySearch(),那麼將產生難以預料的結果。

【返回數組】
C和C++不能返回一個數組,只能返回指向數組的指針,因為返回數組使得控制數組的生命周期變得困難,並且容易造成內存洩漏。java允許直接返回一個數組,並且可以由垃圾回收機制回收。

【數組與容器轉換】【無法轉換基本類型數組】

數組轉為List:
代碼如下:

import java.util.*;
public class arrayToList{
    public static void main(String args[]){
        String[] arrayA = {"a","b","c"};
        List listA = java.util.Arrays.asList(arrayA);
        System.out.println("listA: " + listA);

        int[] arrayB = {1,2,3};
        List listB = java.util.Arrays.asList(arrayB);
        System.out.println("listB: " + listB);

        Integer[] arrayC = {1,2,3};
        List listC = java.util.Arrays.asList(arrayC);
        System.out.println("listC: " + listC);
    }
}
輸出:

listA: [a, b, c]
listB: [[I@de6ced]
listC: [1, 2, 3]

為什麼int和Integer輸出會不同呢?

List轉為數組
代碼如下:

import java.util.*;
public class listToArray{
    public static void main(String args[]){
        List<String> list = new ArrayList<String>();
        String[] array;
        list.add("testA");
        list.add("testB");
        list.add("testC");
        System.out.println("list: " + list);

        String[] strings = new String[list.size()];
        array = list.toArray(strings);
        for(int i = 0, j = array.length; i < j; i++){
            System.out.print(array[i] + ",");
        }
    }
}
輸出為:

list: [testA, testB, testC]
testA,testB,testC

【去除重復數據】
利用數組和容器轉換可以方便地去除數組重復數據,不過如果數組過大,效率是一個問題。
代碼如下:

import java.util.*;
public class javaArrayUnique{
    public static void main(String args[]){
        String[] array = {"a","b","a","a","c","b"};
        arrayUnique(array);
        //test
        for(int i = 0, j = arrayUnique(array).length; i < j; i++){
            System.out.print(arrayUnique(array)[i] + ",");
        }
    }

    public static String[] arrayUnique(String[] array){
        List<String> list = new ArrayList<String>();
        for(int i = 0, j = array.length; i < j; i++){
            if(!list.contains(array[i])){
                list.add(array[i]);
            }
        }
        String[] strings = new String[list.size()];
        String[] arrayUnique = list.toArray(strings);
        return arrayUnique;
    }
}

 關於效率問題,我做了一個對比,在我電腦上運行十萬數據的數組大概是577ms,而運行一百萬數據的數據大約要5663ms。這還跟計算機的運行能力有關,但是明顯是隨著數組大小遞增的。
代碼如下:

import java.util.*;
public class javaArrayUnique{
    public static void main(String args[]){
        Double[] array = new Double[100000];
        for(int i = 0, j = array.length; i < j; i++){
            array[i] = Math.ceil(Math.random()*1000);
        }

        Double[] arrayB = new Double[1000000];
        for(int i = 0, j = arrayB.length; i < j; i++){
            arrayB[i] = Math.ceil(Math.random()*1000);
        }

        System.out.println("start");
        long startTime = System.currentTimeMillis();
        arrayUnique(array);
        long endTime = System.currentTimeMillis();
        System.out.println("array unique run time: " +(endTime - startTime) +"ms");

        long startTimeB = System.currentTimeMillis();
        arrayUnique(arrayB);
        long endTimeB = System.currentTimeMillis();
        System.out.println("arrayB unique run time: " +(endTimeB - startTimeB) +"ms");
    }

    public static Double[] arrayUnique(Double[] array){
        List<Double> list = new ArrayList<Double>();
        for(int i = 0, j = array.length; i < j; i++){
            if(!list.contains(array[i])){
                list.add(array[i]);
            }
        }
        Double[] doubles = new Double[list.size()];
        Double[] arrayUnique = list.toArray(doubles);
        return arrayUnique;
    }
}
輸出:

start
array unique run time: 577ms
arrayB unique run time: 5663ms

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved