《零基礎(chǔ) Java 開(kāi)發(fā) 》 第五章 數(shù)組

第五章 數(shù)組

數(shù)組是一個(gè)基礎(chǔ)的數(shù)據(jù)結(jié)構(gòu),它用來(lái)存儲(chǔ)一組相同類型的元素的集合。數(shù)組非常有用,例如Java提供的集合類ArrayList、HashMap等都是基于數(shù)組來(lái)實(shí)現(xiàn)的。

數(shù)組是一種容器,用于存儲(chǔ)數(shù)據(jù)。一旦定義了數(shù)組元素的類型,那么這個(gè)數(shù)組里面就只能存儲(chǔ)這個(gè)類型的元素。需要記住的是,數(shù)組中的元素是從0開(kāi)始索引。

本章我們介紹Java中的數(shù)組,主要內(nèi)容包括:

數(shù)組的創(chuàng)建與初始化
數(shù)組元素訪問(wèn)
數(shù)組的常用操作
多維數(shù)組等。

5.1 數(shù)組的聲明

一維數(shù)組的聲明語(yǔ)法格式有兩種,分別是

Type varName[]; // (1)

Type[] varName; // (2)

這里的Type類型可以是基本類型或任意的引用類型。
通常我們使用第(2)種方式,因?yàn)樗杨愋透兞棵珠_(kāi),語(yǔ)義更加清晰。

例如,我們聲明一個(gè)包含10個(gè)數(shù)字的 int 數(shù)組變量

int[] numbers;

但是,僅僅是上面的聲明語(yǔ)句,我們還不能使用numbers變量。

螢?zāi)豢煺?2017-08-19 11.52.42.png

在 Java 中,需要對(duì)聲明的數(shù)組變量進(jìn)行初始化才能進(jìn)行相關(guān)的操作。

java> int[] numbers = null;
int[] numbers = null

這里的 null 是引用類型的默認(rèn)值。這個(gè) null 值在 Java 中是一個(gè)非常特殊的值,我們將會(huì)在后面的章節(jié)中探討。上面的代碼會(huì)在棧內(nèi)存中存儲(chǔ)一個(gè)關(guān)于numbers數(shù)組變量的信息,我們可以用下面的圖來(lái)表示

聲明數(shù)組變量 numbers

此時(shí)的numbers變量里已經(jīng)存儲(chǔ)了數(shù)組的類型信息了。

java> numbers instanceof  Object
java.lang.Boolean res2 = false

上面的數(shù)組對(duì)象的聲明其實(shí)跟普通類的對(duì)象聲明是一樣的

java> class Person{}
Created type Person
java> Person p = null;
java.lang.Object p = null
java> p instanceof Person
java.lang.Boolean res12 = false

5.2 數(shù)組對(duì)象實(shí)例創(chuàng)建與初始化

數(shù)組在Java中其實(shí)也是一個(gè)對(duì)象,數(shù)組實(shí)例同樣是使用new操作符創(chuàng)建的。只不過(guò)數(shù)組的聲明語(yǔ)法比較特殊,它使用的是元素的類型加中括號(hào) Type[] varName 的方式, 而普通的類型聲明只需要使用 Type varName即可。

5.2.1 數(shù)組對(duì)象的創(chuàng)建

我們使用 new 關(guān)鍵字來(lái)創(chuàng)建一個(gè)數(shù)組對(duì)象實(shí)例。格式為:

數(shù)組元素類型[] 數(shù)組名 = new 數(shù)組元素類型[length];

這個(gè)new 的過(guò)程會(huì)在堆空間中給我們的數(shù)組開(kāi)辟內(nèi)存空間。其中,length是數(shù)組的容量大小。數(shù)組是一個(gè)固定長(zhǎng)度的數(shù)據(jù)結(jié)構(gòu),一旦聲明了,那么在這個(gè)數(shù)組的生命周期內(nèi)就不能改變這個(gè)數(shù)組的長(zhǎng)度了。如果我們想動(dòng)態(tài)擴(kuò)容,就需要對(duì)數(shù)組進(jìn)行拷貝來(lái)實(shí)現(xiàn)。ArrayList 的動(dòng)態(tài)擴(kuò)容就是使用的Arrays.copyOf方法。Arrays.copyOf 方法又使用了System.arraycopy 這個(gè) native 本地方法。我們會(huì)在下面的小節(jié)中介紹。感興趣的同學(xué)還可以閱讀一下java.util.ArrayList類的代碼。

數(shù)組是一種非常快的數(shù)據(jù)結(jié)構(gòu),如果已經(jīng)知道元素的長(zhǎng)度,那么就應(yīng)該使用數(shù)組而非ArrayList等數(shù)據(jù)結(jié)構(gòu)。

例如:

java> numbers = new int[10]
int[] numbers = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

這個(gè)過(guò)程圖示如下

創(chuàng)建一個(gè)數(shù)組對(duì)象實(shí)例

因?yàn)閿?shù)組是引用類型,它的元素相當(dāng)于類的成員變量,因此數(shù)組分配空間后,每個(gè)元素也被按照成員變量的規(guī)則被隱式初始化。例如,沒(méi)有初始化的整型數(shù)組元素都將默認(rèn)值為0,沒(méi)有初始化的boolean值是false, String對(duì)象數(shù)組是null。

java> boolean[] barray = new boolean[2]
boolean[] barray = [false, false]

數(shù)組的內(nèi)置屬性length指定了數(shù)組長(zhǎng)度

java> numbers.length
java.lang.Integer res13 = 10
java> barray.length
java.lang.Integer res17 = 2

5.2.2 數(shù)組的初始化

我們既可以選擇在創(chuàng)建數(shù)組的時(shí)候初始化數(shù)組,也可以以后初始化。

如果我們想在創(chuàng)建數(shù)組的同時(shí)就初始化元素,使用下面的方式

java> int[] numbers = new int[]{0,1,2,3,4,5,6,7,8,9}
int[] numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

我們還可以省去 new int[], 直接使用花括號(hào)

java> int[] numbers = {0,1,2,3,4,5,6,7,8,9}
int[] numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

這種極簡(jiǎn)單的形式,我們叫做數(shù)組字面量(Array Literals)。

需要注意的是, 如果我們使用一個(gè)未作初始化的數(shù)組對(duì)象,會(huì)導(dǎo)致空指針異常

java> int[] x = null;
int[] x = null
java> x[0]
java.lang.NullPointerException

我們也可以把數(shù)組定義以及分配內(nèi)存空間的操作和賦值的操作分開(kāi)進(jìn)行,例如:

java> String[] s = new String[3];
java.lang.String[] s = [null, null, null]
java> s[0] = "abc";
java.lang.String res23 = "abc"
java> s[1]="xyz";
java.lang.String res24 = "xyz"
java> s[2]="opq";
java.lang.String res25 = "opq"
java> s
java.lang.String[] s = ["abc", "xyz", "opq"]

通常我們會(huì)使用 for 循環(huán)來(lái)初始化數(shù)組的元素, 例如:

java> int[] numbers = new int[10];
int[] numbers = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
java> for(int i = 0; i < 10; i++){
          numbers[i] = i * i;
      }

java> numbers
int[] numbers = [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

5.3 數(shù)組元素的訪問(wèn)

我們使用數(shù)組索引(下標(biāo))來(lái)訪問(wèn)數(shù)組的元素。另外,值得注意的是Java中的數(shù)組的邊界檢查,如果程序訪問(wèn)無(wú)效的數(shù)組索引,Java會(huì)拋出 ArrayIndexOutOfBoundException 異常。例如

java> String[] s = new String[3];
java.lang.String[] s = [null, null, null]
java> s[-1]
java.lang.ArrayIndexOutOfBoundsException: -1
java> s[3]
java.lang.ArrayIndexOutOfBoundsException: 3
java> s[4]
java.lang.ArrayIndexOutOfBoundsException: 4

我們可以看出,負(fù)數(shù)索引在Java中是無(wú)效的,會(huì)拋出ArrayIndexOutOfBoundException 。如果我們用大于等于數(shù)組長(zhǎng)度的無(wú)效的索引來(lái)訪問(wèn)數(shù)組元素時(shí)也會(huì)拋出異常。

5.3.1 數(shù)組的索引

Java 的數(shù)組索引起始于0,[0]返回第一個(gè)元素,[length-1]返回最后一個(gè)元素。代碼示例如下

java> int[] x = {1,2,3,4,5}
int[] x = [1, 2, 3, 4, 5]
java> x[0]
java.lang.Integer res26 = 1
java> x[x.length-1]
java.lang.Integer res27 = 5

我們可以看出,數(shù)組的索引index可以是整型常量或整型表達(dá)式。

需要注意的是,只有當(dāng)聲明定義了數(shù)組,并用運(yùn)算符new為之分配空間或者把這個(gè)數(shù)組引用變量指向一個(gè)數(shù)組對(duì)象空間,才可以訪問(wèn)(引用)數(shù)組中的每個(gè)元素。

需要特別注意的是,這里的length是一個(gè)屬性,不是方法,沒(méi)有加括號(hào)(),我們這里特別說(shuō)明是為了和String的length()方法做區(qū)別。

5.3.2 數(shù)組的存儲(chǔ)

數(shù)組存儲(chǔ)在Java堆的連續(xù)內(nèi)存空間。如果沒(méi)有足夠的堆空間,創(chuàng)建數(shù)組的時(shí)候會(huì)拋出 OutofMemoryError :

java> int[] xLargeArray = new int[10000000*1000000000]
java.lang.OutOfMemoryError: Java heap space

不同類型的數(shù)組有不同的類型,例如下面例子,intArray.getClass()不同于floatArray.getClass()

java> int[] intArray = new int[10]
int[] intArray = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
java> float[] floatArray = new float[10]
float[] floatArray = [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]

java> intArray.getClass()
java.lang.Class res5 = class [I
java> floatArray.getClass()
java.lang.Class res7 = class [F

我們不能存儲(chǔ)double值在int數(shù)組中,否則導(dǎo)致編譯錯(cuò)誤。

java> intArray[5]=1.2
ERROR: incompatible types: possible lossy conversion from double to int
    intArray[5]=1.2;
                ^

但是反過(guò)來(lái)是可以的

java> floatArray[5]=1
java.lang.Float res8 = 1.0

因?yàn)?Java 有類型默認(rèn)轉(zhuǎn)換的機(jī)制。

5.3.3 遍歷數(shù)組元素

for循環(huán)是一種迭代整個(gè)數(shù)組便捷方法。我們可以使用for循環(huán)初始化整個(gè)數(shù)組、訪問(wèn)的每個(gè)索引或更新、獲取數(shù)組元素。

int[] numbers = new int[]{10, 20, 30, 40, 50};
 
for (int i = 0; i < numbers.length; i++) {
  System.out.println("element at index " + i + ": " + numbers[i]);
}

輸出

element at index 0: 10
element at index 1: 20
element at index 2: 30
element at index 3: 40
element at index 4: 50

Java5中開(kāi)始提供for each循環(huán),使用for each循環(huán)可以避免ArrayIndexOutOfBoundException。這里是一個(gè)for each循環(huán)迭代的例子:

for(int i: numbers){
   System.out.println(i);
}

輸出:
10
20
30
40
50

正如你看到的,for each循環(huán)不需要檢查數(shù)組索引,如果你想逐個(gè)地訪問(wèn)所有的元素這是一種很好的方法。

但是同時(shí)因?yàn)槲覀儾荒茉L問(wèn)索引,所以就不能修改數(shù)組元素的值了。

5.4 數(shù)組操作常用API

本節(jié)我們介紹數(shù)組的常用操作,包括Arrays 類 API、拷貝數(shù)組等。

Java API中提供了一些便捷方法通過(guò)java.utils.Arrays類去操作數(shù)組,通過(guò)使用Arrays類提供的豐富的方法,我們可以對(duì)數(shù)組進(jìn)行排序,還可以快速二分查找數(shù)組元素等。

Arrays類的常用方法如下表所示:

方法 功能說(shuō)明
toString() 將數(shù)組的元素以[1, 2, 3, 4, 5] 這樣的字符串形式返回
asList 數(shù)組轉(zhuǎn)List
copyOf() 將一個(gè)數(shù)組拷貝到一個(gè)新的數(shù)組中
sort() 將數(shù)組中的元素按照升序排列
binarySearch() 二分查找方法:在數(shù)組中查找指定元素,返回元素的索引。如果沒(méi)有找到返回-1。 注意:使用二分查找的時(shí)候,數(shù)組要先排好序。

Arrays.toString : 將數(shù)組轉(zhuǎn)化成字符串

如果我們直接對(duì)一個(gè)數(shù)組調(diào)用 Object對(duì)象的 默認(rèn)toString 方法,我們會(huì)得到如下輸出

java> x
int[] x = [1, 2, 3, 4, 5]
java> x.toString()
java.lang.String res33 = "[I@1ddcf61f"

這樣的信息,通常不是我們想要的。Arrays.toString()方法提供了一個(gè)更加有用的輸出

java> Arrays.toString(x)
java.lang.String res34 = "[1, 2, 3, 4, 5]"

Arrays.toString針對(duì)基本類型提供了如下8個(gè)簽名的方法

toString(boolean[] a)
toString(byte[] a)
toString(char[] a)
toString(double[] a)
toString(float[] a)
toString(int[] a)
toString(long[] a)
toString(short[] a)

對(duì)于引用類型,則提供了 toString(Object[] a) 方法。下面是 toString 傳入一個(gè)引用類型參數(shù)的例子。


Person[] persons = new Person[2];
Person jack = new Person();
jack.name = "Jack";
jack.age = 18;
persons[0] = jack;
persons[1] = new Person();
println(Arrays.toString(persons));

輸出:

[Person{name='Jack', age=18}, Person{name='null', age=0}]

其中,Person 類的代碼如下

class Person {
    String name;
    int age;

    @Override
    public String toString() {
        return "Person{" +
            "name='" + name + '\'' +
            ", age=" + age +
            '}';
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

Arrays.asList: 數(shù)組轉(zhuǎn)List

Java中數(shù)組可以輕易的轉(zhuǎn)換成ArrayList。ArrayList是一個(gè)使用頻率非常高的集合類。ArrayList的優(yōu)點(diǎn)是可以改變?nèi)萘看笮。珹rrayList的動(dòng)態(tài)擴(kuò)容實(shí)現(xiàn)是通過(guò)創(chuàng)建一個(gè)容量更大的數(shù)組,然后拷貝當(dāng)前數(shù)組的元素到這個(gè)新的數(shù)組來(lái)實(shí)現(xiàn)。

代碼示例

        Integer[] bigX = {1,2,3};
        List<Integer> bigXlist = Arrays.asList(bigX);
        println("bigXlist size: " + bigXlist.size());
        println(JSON.toJSONString(bigXlist));

        String[] s = {"a","b","c"};
        List slist = Arrays.asList(s);
        println("slist size: " + slist.size());
        println(JSON.toJSONString(slist));

輸出:

bigXlist size: 3
[1,2,3]
slist size: 3
["a","b","c"]

通過(guò)把數(shù)組轉(zhuǎn)成 List,我們就可以方便地使用集合類的常用工具類方法了。例如,我們想要檢查一個(gè)數(shù)組是否包含某個(gè)值,就可以如下實(shí)現(xiàn)

String[] s = {"a","b","c"};
List slist = Arrays.asList(s);
boolean b = slist.contains("a");  
System.out.println(b);  
// true  

需要注意的是,如果我們?cè)谑褂没绢愋蛠?lái)聲明的數(shù)組上面調(diào)用Arrays.asList方法,結(jié)果可能并不是我們想要的

        int[] x = {1,2,3};
        List<int[]> xlist = Arrays.asList(x);
        println("xlist size: " + xlist.size());
        println(JSON.toJSONString(xlist));

輸出

xlist size: 1
[[1,2,3]]

這個(gè) xlist 的 size 居然是 1 ?! 好奇怪。而且 int[] elementOfXList = xlist.get(0) 。這跟沒(méi)調(diào)用 asList 的效果一樣,我們拿到的仍然是個(gè)數(shù)組。

其實(shí),這跟Arrays.asList的實(shí)現(xiàn)本身有關(guān)。

當(dāng)使用 int[] 類型聲明數(shù)組時(shí), ArrayList 構(gòu)造函數(shù)這里的array 參數(shù)類型是
int[1][] ,如下圖所示

使用 int[] 類型聲明數(shù)組的ArrayList 構(gòu)造函數(shù)array 參數(shù)

而我們使用 Integer 類型聲明數(shù)組時(shí),ArrayList 構(gòu)造函數(shù)這里的array 參數(shù)類型是Integer[3] ,如下圖所示

使用 Integer[] 類型聲明數(shù)組的ArrayList 構(gòu)造函數(shù)array 參數(shù)

所以,我們不要使用Arrays.asList 方法來(lái)轉(zhuǎn)換基本類型聲明的數(shù)組時(shí)。如果要轉(zhuǎn)換一定要使用基本類型的包裝類型,這樣才能得到你想要的結(jié)果。

Arrays.copyOf:拷貝數(shù)組

java.lang.System類提供了一個(gè) native方法來(lái)拷貝元素到另一個(gè)數(shù)組。arraycopy方法簽名如下

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

我們可以通過(guò)srcPos參數(shù)指定源數(shù)組 src 的拷貝下標(biāo)位置,dest是目標(biāo)數(shù)組,destPos是目標(biāo)數(shù)組的拷貝下標(biāo)位置, length參數(shù)來(lái)指定拷貝長(zhǎng)度。。代碼示例:

我們先創(chuàng)建源數(shù)組

java> String[] src = {"Java","Kotlin","Scala","JS"};
java.lang.String[] src = ["Java", "Kotlin", "Scala", "JS"]

目標(biāo)數(shù)組

java> String[] dest = new String[7]
java.lang.String[] dest = [null, null, null, null, null, null, null]

從下標(biāo)0開(kāi)始拷貝,src 元素全部拷貝到 dest 中

System.arraycopy(src,0,dest,0,src.length)

結(jié)果

java> dest
java.lang.String[] dest = ["Java", "Kotlin", "Scala", "JS", null, null, null]

如果源數(shù)據(jù)數(shù)目超過(guò)目標(biāo)數(shù)組邊界會(huì)拋出IndexOutOfBoundsException異常

java> System.arraycopy(src,0,dest,0, 10)
java.lang.ArrayIndexOutOfBoundsException

我們可以看到,使用 System.arraycopy 方法,我們還要?jiǎng)?chuàng)建一個(gè) dest 數(shù)組。有點(diǎn)費(fèi)事。不用擔(dān)心,Arrays 類中已經(jīng)為我們準(zhǔn)備好了 copyOf 方法。我們可以直接調(diào)用 copyOf 方法對(duì)數(shù)組進(jìn)行擴(kuò)容。函數(shù)定義如下

public static <T> T[] copyOf(T[] original, int newLength) {
        return (T[]) copyOf(original, newLength, original.getClass());
    }

其中方法實(shí)現(xiàn)里面調(diào)用的 copyOf 實(shí)現(xiàn)如下

    public static <T,U> T[] copyOf(U[] original, int newLength, Class<? extends T[]> newType) {
        @SuppressWarnings("unchecked")
        T[] copy = ((Object)newType == (Object)Object[].class)
            ? (T[]) new Object[newLength]
            : (T[]) Array.newInstance(newType.getComponentType(), newLength);
        System.arraycopy(original, 0, copy, 0,
                         Math.min(original.length, newLength));
        return copy;
    }

我們可以看出其內(nèi)部實(shí)現(xiàn)也是調(diào)用了System.arraycopy方法。相當(dāng)于是對(duì)System.arraycopy方法的再高一層次的抽象。在程序設(shè)計(jì)中,進(jìn)行向上一層的抽象是最本質(zhì)也是最實(shí)用的方法論之一。

代碼示例:

java> s = Arrays.copyOf(s, s.length * 2)
java.lang.String[] s = ["Java", "Kotlin", "Scala", "JS", null, null, null, null]

Arrays.sort:數(shù)組元素排序

對(duì)數(shù)組元素進(jìn)行升序排序。代碼示例

java> Integer[] x = {10,2,3,4,5}
java.lang.Integer[] x = [10, 2, 3, 4, 5]
java> Arrays.sort(x)

java> x
java.lang.Integer[] x = [2, 3, 4, 5, 10]

java> String[] s = {"abc", "cba", "bca"}
java.lang.String[] s = ["abc", "cba", "bca"]
java> Arrays.sort(s)

java> s
java.lang.String[] s = ["abc", "bca", "cba"]

需要注意的是,調(diào)用 sort 方法時(shí),傳入的數(shù)組中的元素不能有 null 值,否則會(huì)報(bào)空指針異常

String[] s = {"JS", "Java", "Kotlin", "Scala", null, null, null, null}
java.lang.String[] s = ["JS", "Java", "Kotlin", "Scala", null, null, null, null]
java> Arrays.sort(s)
java.lang.NullPointerException

Arrays.binarySearch: 在傳入的數(shù)組中二分查找指定的元素

我們首先使用簡(jiǎn)單的代碼示例來(lái)看一下這個(gè)方法的使用

java> Integer[] x = {2,3,4,5,10}
java.lang.Integer[] x = [2, 3, 4, 5,10]
java> Arrays.binarySearch(x, 3)
java.lang.Integer res40 = 1
java> Arrays.binarySearch(x, 10)
java.lang.Integer res41 = 4
java> Arrays.binarySearch(x, 0)
java.lang.Integer res42 = -1

如果找到元素,返回其下標(biāo); 如果沒(méi)找到,返回 -1 。

這個(gè)binarySearch方法定義如下

    public static int binarySearch(int[] a, int key) {
        return binarySearch0(a, 0, a.length, key);
    }

其中,binarySearch0則是標(biāo)準(zhǔn)的二分查找算法的實(shí)現(xiàn)

    private static int binarySearch0(int[] a, int fromIndex, int toIndex,
                                     int key) {
        int low = fromIndex;
        int high = toIndex - 1;

        while (low <= high) {
            int mid = (low + high) >>> 1;
            int midVal = a[mid];

            if (midVal < key)
                low = mid + 1;
            else if (midVal > key)
                high = mid - 1;
            else
                return mid; // key found
        }
        return -(low + 1);  // key not found.
    }

二分查找算法要求待查找的數(shù)組必須是有序的。如果是無(wú)序的查找,我們通常只能遍歷所有下標(biāo)來(lái)搜索了。代碼如下

    public int search(int[] nums, int target) {
        // 遍歷每個(gè)元素
        for (int i=0; i<nums.length; i++) {
            if (nums[i] == target) {
                return i; // 找到元素,返回其下標(biāo)
            }
        }

        // 如果沒(méi)找到target
        return -1;
    }

5.5 多維數(shù)組

我們首先來(lái)創(chuàng)建一個(gè)2行3列的多維數(shù)組:

java> int[][] multiArray = new int[2][3]
int[][] multiArray = [[0, 0, 0], [0, 0, 0]]

這是一個(gè)長(zhǎng)度是2的數(shù)組,它的每個(gè)元素 ( 例如 [0, 0, 0] )里保存的是長(zhǎng)度為3的數(shù)組。 多維數(shù)組其實(shí)也可以叫嵌套數(shù)組。下面是初始化多維數(shù)組的例子:

java> int[][] multiArray = {{1,2,3},{10,20,30}}
int[][] multiArray = [[1, 2, 3], [10, 20, 30]]

java> multiArray[0]
int[] res44 = [1, 2, 3]
java> multiArray[1]
int[] res45 = [10, 20, 30]

我們可以使用下面的圖來(lái)形象地說(shuō)明多維數(shù)組的含義

多維數(shù)組示意圖

多維數(shù)組就是以數(shù)組為元素的數(shù)組。上面的二維數(shù)組就是一個(gè)特殊的一維數(shù)組,其每一個(gè)元素都是一個(gè)一維數(shù)組。

我們可以先聲明多維數(shù)組的第1維的長(zhǎng)度,第2維的長(zhǎng)度可以單獨(dú)在初始化的時(shí)候再聲明。例如:

我們首先聲明一個(gè)2行的數(shù)組,這里我們并沒(méi)有指定每一列的元素長(zhǎng)度。代碼如下

java> String[][] s = new String[2][]
java.lang.String[][] s = [null, null]

圖示如下

聲明一個(gè)2行的數(shù)組

我們來(lái)為每一行元素賦值,我們要的賦給每一行的值也是一個(gè) String 數(shù)組

java> s[0] = new String[2]
java.lang.String[] res46 = [null, null]
java> s[1] = new String[3]
java.lang.String[] res47 = [null, null, null]
java> s
java.lang.String[][] s = [[null, null], [null, null, null]]

其中,s[0]=new String[2] 和 s[1]=new String[3] 是限制第2維各個(gè)數(shù)組的長(zhǎng)度。

如下圖所示

s[0]=new String[2] 和 s[1]=new String[3]

這個(gè)時(shí)候,我們已經(jīng)基本看到了這個(gè)多維數(shù)組的結(jié)構(gòu)了 [[null, null], [null, null, null]] 。 第1行是一個(gè)有2個(gè)元素的數(shù)組,第2行是一個(gè)有3個(gè)元素的數(shù)組。

然后,我們對(duì)每行每列的元素進(jìn)行賦值

java>         s[0][0] = new String("Java");
java.lang.String res49 = "Java"
java>         s[0][1] = new String("Scala");
java.lang.String res50 = "Scala"
java>         s[1][0] = new String("Kotlin");
java.lang.String res51 = "Kotlin"
java>         s[1][1] = new String("SpringBoot");
java.lang.String res52 = "SpringBoot"
java>         s[1][2] = new String("JS");
java.lang.String res53 = "JS"

最終,我們的數(shù)組被初始化為

java> s
java.lang.String[][] s = [["Java", "Scala"], ["Kotlin", "SpringBoot", "JS"]]

二維數(shù)組中的元素引用方式為 arrayName[index1][index2]。 代碼示例如下

java> s[0][1]
java.lang.String res54 = "Scala"
java> s[1][0]
java.lang.String res55 = "Kotlin"

訪問(wèn)不存在的元素,同樣拋出ArrayIndexOutOfBoundsException 異常

java> s[0][2]
java.lang.ArrayIndexOutOfBoundsException: 2

本章小結(jié)

本章示例代碼: https://github.com/EasyJava2017/basics

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,797評(píng)論 6 531
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,179評(píng)論 3 414
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人,你說(shuō)我怎么就攤上這事。” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 175,628評(píng)論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我,道長(zhǎng),這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 62,642評(píng)論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 71,444評(píng)論 6 405
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 54,948評(píng)論 1 321
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,040評(píng)論 3 440
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 42,185評(píng)論 0 287
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,717評(píng)論 1 333
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 40,602評(píng)論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 42,794評(píng)論 1 369
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,316評(píng)論 5 358
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,045評(píng)論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 34,418評(píng)論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 35,671評(píng)論 1 281
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 51,414評(píng)論 3 390
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 47,750評(píng)論 2 370

推薦閱讀更多精彩內(nèi)容