天天看點

我的Thinking in Java學習筆記(八)

  Array的初始化

    array其實就是一組對象或者一組基本資料類型的資料,每一個array中的資料必須是同一種類型,并且以一個标示符封裝在一起

    例如    int[] i;    或者  int i[];

    現在你這樣聲明一個array,但是array裡面儲存的其實是一組句柄,而非具體的資料對象,你必須要撰寫初始化語句才能 讓array變的有意義,初始化的方式同樣有2種

      int i[] = new int[3];或者是int i[] = { 1,2,3 };

    需要注意的是第二種初始化方法,隻能出現在array生成的時候。java允許你将某個array指派給另一個array,你所傳遞的其實隻是句柄罷了,我們看個例子

     public class arrays

    {

     public static void main(String args[])

     {

      int[] i = {1,2,3}; //聲明一個數組,并且初始化

      int[] ii; //隻是聲明一個數組

      ii = i; //句柄的傳遞,并未把數組内的值傳遞,換句話說就是此時ii和i的句柄已經同時指向同一個記憶體位址

      for(int j = 0; j<ii.length; j++)

      {

       ii[j]++; //我們隻改變ii的值

      }

      for(int j = 0; j<i.length; j++)

      {

       System.out.println(" i[ "+j+" ]= "+i[j]); //顯示i的值

      }

     }

    }

    我們回發現,i的值随着ii的改變而改變了,這個現象我們在指派運算的時候已經講過了。我們需要知道,任何一個array都有一個特性,通過他你可以知道array内的元素的個數,那就是length,因為java是從0開始檢索數組的,也就是說該數組的最大索引值是length-1。如果你的索引值大于/小于實際容納元素值,那麼就會在程式的執行期得到數組越界例外,因為java會對數組進行邊界檢查,是以array的效率不是很高。如果你并不知道你所需要能能容納多少元素的array,但是你卻需要這麼一個array,你可以采用new的方式來生成

      public class arrays

     {

      public static void main(String args[])

      {

       int i[] = new int[3];

       for(int j = 0; j<i.length; j++)

       {

        System.out.println(" i[ "+j+" ]= "+i[j]); //顯示3個0

       }

      }

     }

    基本類型的array會自動初始化為0(與基本資料類型的成員資料的初始化值是一樣的),但是你要是産生對象數組的話,你就必須指定初始化值

      public class arrays

     {

      public static  void go(Object[] o) //可以接受未定類型和個數的數組

      {

       for(int i=0;i<o.length;i++)     

        System.out.println(o[i]);

      }

      public static void show()

      {

       String[] s = new String[3]; //聲明可以容納3個元素對象數組,但是他們其實是3個句柄組成的句柄數組,并沒有指向任何具體的記憶體塊

       s[0]="one"; //分别給每個句柄連接配接實際的對象,這才完成初始化動作,如果要是沒有這一步,就會顯示的是null

       s[1]="two";

       s[2]="three";

       for(int j = 0; j<s.length; j++)

       {

        System.out.println(" i[ "+j+" ]= "+s[j]);

       }

      }

      public static void main(String args[])

      {

       arrays.go(new Object[] {new String("a"),new String("b"),new String("c")});

       arrays.show();

      }

     }

     還有一種方法

     public class arrays

     {

      public static void main(String args[])

      {

       String[] s = {"1","2","3"}; //因為數組的容量在編譯期就确定了,是以用途很小

       for(int j = 0; j<s.length; j++)

       {

        System.out.println(" i[ "+j+" ]= "+s[j]);

       }

      }

     }

      多元數組

        public class arrays

       {

        public static void main(String args[])

        {

         System.out.println("This is Mulitdimentsional Arrays Demo One");

         int[] [] ii={{1,2,3},{2,3,4}};

         for(int i=0; i<ii.length ;i++)

         {

          for(int j = 0; j< ii[i].length ; j++)

          {

           System.out.println(" i["+i+"] ["+j+"]="+ii[i] [j]);

          }

         }

         System.out.println("This is Mulitdimentsional Arrays Demo Two");

         int[] [] [] iii = new int[2] [3] [4];

         for(int i=0;i<iii.length;i++)

          for(int j=0;j<iii[i].length;j++)

           for(int k=0;k<iii[i] [j].length;k++)

            System.out.println(" i["+i+"]["+j+"]["+k+"] = "+iii[i] [j] [k]);

         System.out.println("This is Mulitdimentsional Arrays Demo Three"); 

         Integer[] [] II= new Integer[2] [];

         for(int i=0;i<II.length;i++)

         {

          II[i]=new Integer[5];

          for(int j=0;j<II[i].length;j++)

          {

           II[i][j]=new Integer(4);

           System.out.println(" i["+i+"] ["+j+"]="+II[i] [j]);

          }

         }

        }

       }

       注意:多元數組中的每一組中括号代表arrays的層次,中括号從左到右分别代表大括号的從外到内

   習題解答:

      因為有的題目比較簡單,實在是沒有講解的意義,我會把稍微有點難度的題目拿出來解答,但是也許大家的程度不一樣,有的題目人家不覺得容易的你卻覺得很容易,如果是這樣的話,誰有問題可以從qq上或mail上告訴我,我會把答案給你寫出來

      12、撰寫具有finalize()的class,并且保證他一定會被調用

        class test

       {

        protected  void finalize()

        {

         System.out.println(" finalize() running......");

        }

        public static void main(String args[])

        {

         new test(); //注意這裡為什麼寫成new test(),而不寫成test t = new test();原因就是這樣寫更容易引起垃圾回收器的注意

         System.gc();

        }

       }

       使用System.gc();可能會讓你的finalize()調用,記住我們隻是說可能,System.gc();隻是一個請求,但是至于是否執行,不得而知。大家一定要記住,無論是垃圾回收還是終結動作,都不一定保證會發生,如果jvm沒有面臨資源緊張的情況,那麼,他就不會去執行清理動作,以節省系統開支

       Basically, there’s no way to ensure that finalize( ) will be called.

      13、撰寫一個名叫tank的類,此類的狀态是滿的或者是空的,他的死亡條件是,對象在清理的時候必須是空的,請撰寫finalize()函數,來判斷其死亡條件是否成立,并且

      在main 中檢測幾種可能發生的情況

        class Tank

       {

         static int counter = 0;

         int id = counter++;

         boolean full = false;

         public Tank()

         {

           System.out.println("Tank " + id + " created");

           full = true;

         }

         public void empty()

         {

           full = false;

         }

         protected void finalize()

         {

           if(full)

             System.out.println( "Error: tank " + id +" must be empty at cleanup");

           else

             System.out.println( "Tank " + id + " cleaned up OK");

         }

       }

       class tankTest

       {

        public static void main(String args[])

        {

          new Tank();

          new Tank().empty();

         System.gc();

        }

       }

      16、撰寫一個類,其中有2個string資料,一個在構造函數初始化,一個在定義處初始化,這2中方法有什麼差別

        class test

       {

        String s1="hello!";

        String s2;

        public test(String s)

        {

         s2=s;

        }

        public static void main(String args[])

        {

         test t =new test("goodbye");

         System.out.println(t.s1); //static的函數隻可以調用static的資料和函數,但是對象.資料的方式除外

         System.out.println(t.s2);

        }

       }

       s1的初始化動作是在構造函數調用之前就完成的~,而與此同時s2也被初始化,但是他被初始化成null,以後s2可以根據傳遞給構造函數的值的變化而變化,

       更具有柔韌性。

      18、撰寫一個class,有一個string 資料,使用實體初始化的方式,并且說出與本書不同的用途

         class test

        {

         String s;

         {

          s="hello!";  //注意不要寫成 String s="hello",否則就成局部變量了!

          System.out.println("Instance before constructor ");

         }

         test()

         {

          System.out.println(s+"from test()");

         }

         public static void main(String args[])

         {

          test t=new test();

         }

        }

        書上的說的用途是,這種用法在匿名内部類(現在還沒學到)中是必須用到,因為構造函數需要有個函數名,但是匿名内部類是沒有名字的 ,于是我們需要用這種方法來初始化資料!我們再來說個用途:在一般的class中,實體初始化方式是在構造函數調用之前調用的,那麼既然這樣,這個程式會先顯示Instance before constructor再顯示hello! from test(),足以說明問題。

      20、撰寫一個函數,能夠産生三維數組并且初始化,數組的容量由函數的引數決定,array的初始值必須是在函數因數所指定的範圍内,再撰寫一個函數,

        可以列印出數組。在main函數中需要能夠産生不同容量的數組

         class test

        {

         //接受引數的函數,x、y、z分别代表數組中的元素,d1、d2代表數組的範圍,并且該函數可以傳回一個數組

         public static double[][][] createArray(int x , int y , int z ,double d1,double d2)

         {

          double[][][] darray = new double[x][y][z]; //定義一個數組,未初始化

          double incr = (d1-d2)/(x * y * z); //計算每個數組值的增量,因為咱們數組的值要在d1-d2的範圍中

          double value=d2; //數組中每一個元素的值,并且讓他初始值等于傳遞引數的最小值

          for( int i =0 ; i<darray.length ; i++)  //初始化數組

           for( int j =0 ; j < darray[i].length ; j++)

             for( int k =0 ; k < darray[i][j].length ; k++)

             {

              darray[i][j][k]=value;  //給每個元素指派值

              value=incr+value;  //重新類加值,用于下次運算

             }

          return darray;  //傳回一個數組

         }

         public static void showArray(double[][][] darray)   //顯示數組的函數

         {

          for( int i =0; i<darray.length ; i++)

          {

           for( int j=0; j<darray[i].length; j++)

           {

            for( int k =0; k<darray[i][j].length ;k++)

             System.out.println("darray["+i+"]["+j+"]["+j+"] = "+darray[i][j][k]);

           }

           System.out.println("*****************"); //列印分割符

          }

         }

         public static void main(String args[])

         {

          double[][][] test =createArray(2,3,4,11.0,2.0);

          showArray(test);

         }

        }

 好了以上就是第四章所有的内容,知識點的東西很少,基本上全是需要了解的東西,看不懂的地方多看幾便就好了~,我開始的時候看了3遍才明白呢~呵呵~驽鈍

 下一篇我們講解的第五章   隐藏實作細目  希望大家繼續捧場