Java數組總結

最近在重溫基礎,core Java 卷1結合java編程思想,將數組知識點總結如下:

特性

數組是一種引用類型,存儲同一種數據類型的集合容器.

存儲時數組元素存儲在堆內存(heap)中,數組的引用變量存儲在棧內存中(stack)中。

優點:隨機訪問效率高、類型檢查嚴格、可以保存基本類型

1、數組是存儲和隨機訪問效率最高的存儲方式,數組就是一個簡單的線性序列,使得元素訪問非常快速

2、因爲數組只能保存特定類型的數據,編譯期就可以避免數據或插入時弄錯類型。

但也損失了一些特性。

3、數組是唯一一個可以保存基本類型的容器

數組的特點:

    1. 只能存儲同一種數據類型的數據。

    2. 一旦初始化,長度固定。 如果想要擴展就只能創建一個新的數組將原有數組的值引入新的數組中(ArrayList就是這樣保持彈性的,所以使得ArryList比數組效率要低)

    3. 數組中的元素與元素之間的內存地址是連續的。

注意: Object類型的數組可以存儲任意類型的數據。

聲明及創建(初始化)

String[] a;聲明數組;聲明數組僅僅是在內存中開闢出一塊區域,裏面沒有任何東西,相當於只在堆內存中開闢了一塊區域放數組,但是棧內存中沒有對應的引用。

(當一個堆內存對象沒有任何引用變量指向它時,系統的垃圾回收器纔會在合適的時候回收它)

擴展:棧內存和堆內存

1》棧內存

    當一個方法執行時,每個方法都會建立自己的內存棧,

     在這方法內定義的變量將會逐個放入這塊棧內存裏,

    隨着方法的執行結束,這個方法的內存棧也將自然銷燬。

    所有在方法中定義的局部變量都是存放在棧內存中的;

2堆內存   

   在程序中創建一個對象時,這個對象將被保存到運行時數據區中,

    以便反覆利用(因爲對象的創建成本通常較大),

    這個運行時數據區就是堆內存。

   堆內存中的對象不會隨方法的結束而銷燬,

    即使方法結束後,這個對象還可能被另一個引用變量所引用(在方法的參數傳遞時很常見),則這個對象依然不會被銷燬。只有當一個對象沒有任何引用變量指向它時,系統的垃圾回收器纔會在合適的時候回收它。

 

String[] a=new String[];創建數組

數組的默認初始化,基本類型是 0 ,布爾類型是 false,引用類型爲null,所以上面數組初始化後都爲null。

獲得數組長度 用s.length屬性(注意:不是方法)來獲取

ps:String底層都是用char數組來實現的(後續String)研究;

  ArrayList底層也是用數組實現的

一些常用方法

  • l  for循環遍歷

for each循環語句會遍歷數組中每個元素,不需使用下標。

使用傳統for循環:不希望遍歷集合中的每個元素或者在循環內部需要使用下標值的時候。

  • l  數組顯示:Arrays.toString(數組名稱):基本類型和string返回一個包含數組元素的字符串如"[2,3,5,7,8]",其他引用類型輸出地址[core_java.Bean@15db9742,core_java.Bean@15db9742]
  • java中允許數組長度爲0,所以判斷時一般用if(s!=null&&s.length>0)
  • l  數組拷貝:

方式1、int[] i=新的數組名稱:此時這兩個變量引用同一個數組

方式2、Arrays.copyOf(原始數組名,新的長度):如果新的長度>老長度,後面填0,false,null,如果新長度<老長度截取新長度

    擴展:Arrays.copyOf()與system.arrayscopy的區別:

                  1、copyOf底層是用arraysCopy實現的,

                  2、copyOf只能從頭開始複製,arraysCopy可以自定義開始複製的位置。

                  3、copyOf自動創件一個新的數組,arraysCopy需要自己創建數組,

                  4、Arrays.copyOf可以用來擴容數組,system.arrayscopy可以將本數組中不同位置的數據複製到本數組其他位置。

                 5、copyOf方法的組最後一個參數是新數組的長度 可以大於原數組(如果想截取數組某一段長度 可以用copyOf(數組,開始長度,結束長度)),system.arraysCopy最後一個參數是要複製的長度,長度最長不能超過新數組的長度。

                  

                   Arrays.copyOf():方法說明

                   1、首先生成一個新的數組長度等於第二個參數

                   2、然後調用System.arrayscopy()方法拷貝原數組的內容到新數組中。

                   相當於調用了一次System.arrayscopy(old[],0,new[],0,length);

                   3、可以用來擴展數組,例如

                String[] s1=new String[]{"1","2"};

               //擴展數組

               s1=Arrays.copyOf(s1,5);    -------->s1變爲[1, 2, null, null, null]

 

                   System.arrayscopy(old[],old起始位置,new[],new起始位置,複製長度):方法說明

                   1、此方法是native的,說明底層是用c++或c實現的。

                   2、需要自己先new一個數組出來,再將原數組值複製進去

                   3、可以自己複製自己的值到自己數組內

                    int[] fun ={0,1,2,3,4,5,6}; 
                    System.arraycopy(fun,0,fun,3,3);則結果爲:{0,1,2,0,1,2,6};

 

  • l  數組排序:

Arrays.sort: int a[] =new int[2000];……Arrays.sort(a);

Arrays.sort()jdk7以前對基本類型採用調優的快速排序,對對象類型採用了改進的歸併排序,jdk7以後修改了排序策略:如果JVM啓動參數配置了-Djava.util.Arrays.useLegacyMergeSort=true  那麼就會執行原來的排序策略(優化的歸併排序)

 

如果不配置,那麼採用的是TimSort

         public static voidsort(Object[] a) {

        if (LegacyMergeSort.userRequested)

            legacyMergeSort(a);

        else

            ComparableTimSort.sort(a, 0,a.length, null, 0, 0);

   }

 

   /** To be removed in a future release. */

   private staticvoid legacyMergeSort(Object[] a) {

        Object[] aux = a.clone();

        mergeSort(aux, a, 0, a.length, 0);

   }

原始的排序流程是採用了輕量級優化的歸併排序,保證時間複雜度是n(logn),並且保證排序是穩定的,(快排雖然在某些時候效率上高於歸併,但是是不穩定的並且最壞的情況下時間複雜度是o(n^2))。

具體實現這個作者寫的非常好:http://www.cnblogs.com/gw811/archive/2012/10/04/2711746.html

快排對大多數數據集合來說都是高效的

擴展:快速排序、歸併排序及各種排序算法。後續會更新<排序算法學習>

  • l  main函數的參數String[] args作用 
方便外面的數據引入到main函數中。

應用方法:

在命令行中輸入 java  message hello world則程序紅args[0]="hello"args[1]="world"

  • l  斐波那契數列
                0,                n=1
   斐波那契數列定義如下:f(n)= 1,                n=2
                             f(n-1)+f(n-2),    n>2

  • l  多維數組,底層其實沒有多維,只是數組的數組,第一維中每一個元素又是一個數組,保存的是一個數組的引用
  • l  多維數組打印可以用Arrays.deepToString(數組名),底層調用遞歸方式一層層判斷是否爲數組,不是數組打印,是數組遞歸

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章