<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          教妹學(xué) Java 第 27 講:數(shù)組

          共 6201字,需瀏覽 13分鐘

           ·

          2021-05-10 19:56

          “哥,我看你之前的文章里提到,ArrayList 的內(nèi)部是用數(shù)組實(shí)現(xiàn)的,我就對(duì)數(shù)組非常感興趣,想深入地了解一下,今天終于到這個(gè)環(huán)節(jié)了,好期待呀!”三妹的語(yǔ)氣里顯得很興奮。

          “的確是的,看 ArrayList 的源碼就一清二楚了?!蔽乙贿呎f(shuō),一邊打開(kāi) Intellij IDEA,并找到了 ArrayList 的源碼。

          /**
           * The array buffer into which the elements of the ArrayList are stored.
           * The capacity of the ArrayList is the length of this array buffer. Any
           * empty ArrayList with elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA
           * will be expanded to DEFAULT_CAPACITY when the first element is added.
           */

          transient Object[] elementData; // non-private to simplify nested class access

          /**
           * The size of the ArrayList (the number of elements it contains).
           *
           * @serial
           */

          private int size;

          “瞧見(jiàn)沒(méi)?Object[] elementData 就是數(shù)組。”我指著顯示屏上這串代碼繼續(xù)說(shuō)。

          數(shù)組是一個(gè)對(duì)象,它包含了一組固定數(shù)量的元素,并且這些元素的類型是相同的。數(shù)組會(huì)按照索引的方式將元素放在指定的位置上,意味著我們可以通過(guò)索引來(lái)訪問(wèn)這些元素。在 Java 中,索引是從 0 開(kāi)始的。

          “哥,能說(shuō)一下為什么索引從 0 開(kāi)始嗎?”三妹突然這個(gè)話題很感興趣。

          “哦,Java 是基于 C/C++ 語(yǔ)言實(shí)現(xiàn)的,而 C 語(yǔ)言的下標(biāo)是從 0 開(kāi)始的,所以 Java 就繼承了這個(gè)良好的傳統(tǒng)習(xí)慣。C語(yǔ)言有一個(gè)很重要概念,叫做指針,它實(shí)際上是一個(gè)偏移量,距離開(kāi)始位置的偏移量,第一個(gè)元素就在開(kāi)始的位置,它的偏移量就為 0,所以索引就為 0?!贝丝蹋液茏孕?。

          “此外,還有另外一種說(shuō)法。早期的計(jì)算機(jī)資源比較匱乏,0 作為起始下標(biāo)相比較于 1 作為起始下標(biāo),編譯的效率更高?!?/p>

          “哦?!比靡馕渡铋L(zhǎng)地點(diǎn)了點(diǎn)頭。

          我們可以將數(shù)組理解為一個(gè)個(gè)整齊排列的單元格,每個(gè)單元格里面存放著一個(gè)元素。

          數(shù)組元素的類型可以是基本數(shù)據(jù)類型(比如說(shuō) int、double),也可以是引用數(shù)據(jù)類型(比如說(shuō) String),包括自定義類型。

          數(shù)組的聲明方式分兩種。

          先來(lái)看第一種:

          int[] anArray;

          再來(lái)看第二種:

          int anOtherArray[];

          不同之處就在于中括號(hào)的位置,是跟在類型關(guān)鍵字的后面,還是跟在變量的名稱的后面。前一種的使用頻率更高一些,像 ArrayList 的源碼中就用了第一種方式。

          同樣的,數(shù)組的初始化方式也有多種,最常見(jiàn)的是:

          int[] anArray = new int[10];

          看到了沒(méi)?上面這行代碼中使用了 new 關(guān)鍵字,這就意味著數(shù)組的確是一個(gè)對(duì)象,只有對(duì)象的創(chuàng)建才會(huì)用到 new 關(guān)鍵字,基本數(shù)據(jù)類型是不用的。然后,我們需要在方括號(hào)中指定數(shù)組的長(zhǎng)度。

          這時(shí)候,數(shù)組中的每個(gè)元素都會(huì)被初始化為默認(rèn)值,int 類型的就為 0,Object 類型的就為 null。不同數(shù)據(jù)類型的默認(rèn)值不同,可以參照之前的文章。

          另外,還可以使用大括號(hào)的方式,直接初始化數(shù)組中的元素:

          int anOtherArray[] = new int[] {12345};

          這時(shí)候,數(shù)組的元素分別是 1、2、3、4、5,索引依次是 0、1、2、3、4,長(zhǎng)度是 5。

          “哥,怎么訪問(wèn)數(shù)組呢?”三妹及時(shí)地插話到。

          前面提到過(guò),可以通過(guò)索引來(lái)訪問(wèn)數(shù)組的元素,就像下面這樣:

          anArray[0] = 10;

          變量名,加上中括號(hào),加上元素的索引,就可以訪問(wèn)到數(shù)組,通過(guò)“=”操作符可以對(duì)元素進(jìn)行賦值。

          如果索引的值超出了數(shù)組的界限,就會(huì)拋出 ArrayIndexOutOfBoundException。

          既然數(shù)組的索引是從 0 開(kāi)始,那就是到數(shù)組的 length - 1 結(jié)束,不要使用超出這個(gè)范圍內(nèi)的索引訪問(wèn)數(shù)組,就不會(huì)拋出數(shù)組越界的異常了。

          當(dāng)數(shù)組的元素非常多的時(shí)候,逐個(gè)訪問(wèn)數(shù)組就太辛苦了,所以需要通過(guò)遍歷的方式。

          第一種,使用 for 循環(huán):

          int anOtherArray[] = new int[] {12345};
          for (int i = 0; i < anOtherArray.length; i++) {
              System.out.println(anOtherArray[i]);
          }

          通過(guò) length 屬性獲取到數(shù)組的長(zhǎng)度,然后從 0 開(kāi)始遍歷,就得到了數(shù)組的所有元素。

          第二種,使用 for-each 循環(huán):

          for (int element : anOtherArray) {
              System.out.println(element);
          }

          如果不需要關(guān)心索引的話(意味著不需要修改數(shù)組的某個(gè)元素),使用 for-each 遍歷更簡(jiǎn)潔一些。當(dāng)然,也可以使用 while 和 do-while 循環(huán)。

          在 Java 中,可變參數(shù)用于將任意數(shù)量的參數(shù)傳遞給方法,來(lái)看 varargsMethod() 方法:

          void varargsMethod(String... varargs) {}

          該方法可以接收任意數(shù)量的字符串參數(shù),可以是 0 個(gè)或者 N 個(gè),本質(zhì)上,可變參數(shù)就是通過(guò)數(shù)組實(shí)現(xiàn)的。為了證明這一點(diǎn),我們可以看一下反編譯一后的字節(jié)碼:

          public class VarargsDemo
          {

              public VarargsDemo()
              
          {
              }

              transient void varargsMethod(String as[])
              
          {
              }
          }

          所以,我們其實(shí)可以直接將數(shù)組作為參數(shù)傳遞給該方法:

          VarargsDemo demo = new VarargsDemo();
          String[] anArray = new String[] {"沉默王二""一枚有趣的程序員"};
          demo.varargsMethod(anArray);

          也可以直接傳遞多個(gè)字符串,通過(guò)逗號(hào)隔開(kāi)的方式:

          demo.varargsMethod("沉默王二""一枚有趣的程序員");

          在 Java 中,數(shù)組與 List 關(guān)系非常密切。List 封裝了很多常用的方法,方便我們對(duì)集合進(jìn)行一些操作,而如果直接操作數(shù)組的話,有很多不便,因?yàn)閿?shù)組本身沒(méi)有提供這些封裝好的操作,所以有時(shí)候我們需要把數(shù)組轉(zhuǎn)成 List。

          “怎么轉(zhuǎn)呢?”三妹問(wèn)到。

          最原始的方式,就是通過(guò)遍歷數(shù)組的方式,一個(gè)個(gè)將數(shù)組添加到 List 中。

          int[] anArray = new int[] {12345};

          List<Integer> aList = new ArrayList<>();
          for (int element : anArray) {
              aList.add(element);
          }

          更優(yōu)雅的方式是通過(guò) Arrays 類的 asList() 方法:

          List<Integer> aList = Arrays.asList(anArray);

          但需要注意的是,該方法返回的 ArrayList 并不是 java.util.ArrayList,它其實(shí)是  Arrays 類的一個(gè)內(nèi)部類:

          private static class ArrayList<Eextends AbstractList<E>
                  implements RandomAccessjava.io.Serializable
          {}

          如果需要添加元素或者刪除元素的話,需要把它轉(zhuǎn)成 java.util.ArrayList。

          new ArrayList<>(Arrays.asList(anArray));

          Java 8 新增了 Stream 流的概念,這就意味著我們也可以將數(shù)組轉(zhuǎn)成 Stream 進(jìn)行操作。

          String[] anArray = new String[] {"沉默王二""一枚有趣的程序員""好好珍重他"};
          Stream<String> aStream = Arrays.stream(anArray);

          如果想對(duì)數(shù)組進(jìn)行排序的話,可以使用 Arrays 類提供的 sort() 方法。

          • 基本數(shù)據(jù)類型按照升序排列
          • 實(shí)現(xiàn)了 Comparable 接口的對(duì)象按照 compareTo() 的排序

          來(lái)看第一個(gè)例子:

          int[] anArray = new int[] {52148};
          Arrays.sort(anArray);

          排序后的結(jié)果如下所示:

          [12458]

          來(lái)看第二個(gè)例子:

          String[] yetAnotherArray = new String[] {"A""E""Z""B""C"};
          Arrays.sort(yetAnotherArray, 13,
                          Comparator.comparing(String::toString).reversed());

          只對(duì) 1-3 位置上的元素進(jìn)行反序,所以結(jié)果如下所示:

          [A, Z, E, B, C]

          有時(shí)候,我們需要從數(shù)組中查找某個(gè)具體的元素,最直接的方式就是通過(guò)遍歷的方式:

          int[] anArray = new int[] {52148};
          for (int i = 0; i < anArray.length; i++) {
              if (anArray[i] == 4) {
                  System.out.println("找到了 " + i);
                  break;
              }
          }

          上例中從數(shù)組中查詢?cè)?4,找到后通過(guò) break 關(guān)鍵字退出循環(huán)。

          如果數(shù)組提前進(jìn)行了排序,就可以使用二分查找法,這樣效率就會(huì)更高一些。Arrays.binarySearch() 方法可供我們使用,它需要傳遞一個(gè)數(shù)組,和要查找的元素。

          int[] anArray = new int[] {12345};
          int index = Arrays.binarySearch(anArray, 4);

          “除了一維數(shù)組,還有二維數(shù)組,三妹你可以去研究下,比如說(shuō)用二維數(shù)組打印一下楊輝三角。”說(shuō)完,我就去陽(yáng)臺(tái)上休息了,留三妹在那里學(xué)習(xí),不能打擾她。


          點(diǎn)贊越多,更新的動(dòng)力越足喲,瘋狂暗示~

          瀏覽 45
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  特级毛片网站 | 大鸡巴乱伦 | 国产精品成人熊猫视频成人在线播放 | 日韩视频在线观看免费 | 色色射 |