首頁 > Java > java教程 > 主體

關於JAVA 數組的使用介紹

巴扎黑
發布: 2017-05-21 14:08:32
原創
1366 人瀏覽過

本篇文章小編將為大家介紹,關於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&#39;m testA,I have no changed: " + testA);
        arrayB = arrayA;
        arrayB[0] = "arrayB have changed";
        System.out.println("I&#39;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;
    }
}
登入後複製

输出:

startarray unique run time: 577msarrayB unique run time: 5663ms
登入後複製

以上是關於JAVA 數組的使用介紹的詳細內容。更多資訊請關注PHP中文網其他相關文章!

相關標籤:
來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板
關於我們 免責聲明 Sitemap
PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!