1. 程式人生 > 其它 >java基礎知識總結(四)——控制語句、方法、以及遞迴

java基礎知識總結(四)——控制語句、方法、以及遞迴

條件結構

  1、if單分支結構

    語法結構:

      if(布林表示式){

        語句塊

      }

    if語句對布林表示式進行一次判定,若判定為真,則執行{}中的語句塊,否則跳過該語句塊。流程圖如下圖所示。

    

    注意:如果if語句不寫{},則只能作用於後面的第一條語句。

  2、if-else雙分支結構

    語法結構:

      if(布林表示式){

        語句塊1

      }else{

        語句塊2

      }

    當布林表示式為真時,執行語句塊1,否則,執行語句塊2。也就是else部分。流程圖如下如所示。

    

    Tip:條件運算子有時候可用於代替if-else

  3、if-elseif-else多分支結構

    語法結構:

      if(布林表示式1){

        語句塊1;

      }else if(布林表示式2){

        語句塊2;

      }......

      else if(布林表示式n){

        語句塊n;

      }else{

        語句塊n+1;

      }

    當布林表示式1為真時,執行語句塊1;否則,判斷布林表示式2,當布林表示式2為真時,執行語句塊2;否則,繼續判斷布林表示式3······;如果1~n個布林表示式均判定為假時,則執行語句塊n+1,也就是else部分。流程圖如下圖所示。

    

  4、switch語句

    語法結構:

      switch(表示式){

        case值1:

          語句序列1;

          [break];

        case值2:

          語句序列2;

          [break];

        ...............

        [default:

          預設語句;]

        }

    switch語句會根據表示式的值從相匹配的case標籤處開始執行,一直執行到break語句處或者是switch語句的末尾。如果表示式的值與任一case值不匹配,則進入default語句(如果存在default語句的情況)。

    根據表示式值的不同可以執行許多不同的操作。switch語句中case標籤在JDK1.5之前必須是整數(long型別除外)或者列舉,不能是字串,在JDK1.7之後允許使用字串(String)。

    switch多分支結構的流程圖如下圖所示。

    

迴圈結構

  迴圈結構分兩大類,一類是當型,一類是直到型。

  當型:

    當布林表示式條件為true時,反覆執行某語句,當布林表示式的值為false時才停止迴圈,比如:while與for迴圈。

  直到型:

    先執行某語句,再判斷布林表示式,如果為true,再執行某語句,如此反覆,直到布林表示式條件為false時才停止迴圈,比如do-while迴圈。

  

  1、while迴圈

    語法結構:

      while(布林表示式){

        迴圈體;

      }

    在迴圈剛開始時,會計算一次“布林表示式”的值,若條件為真,執行迴圈體。而對於後來每一次額外的迴圈,都會在開始前重新計算一次。      語句中應有使迴圈趨向於結束的語句,否則會出現無限迴圈–––"死"迴圈。while迴圈結構流程圖如下圖所示。     

  2、do-while迴圈

    語法結構:

      do{

        迴圈體;

      }while(布林表示式);

    do-while迴圈結構會先執行迴圈體,然後再判斷布林表示式的值,若條件為真,執行迴圈體,當條件為假時結束迴圈。do-while迴圈的迴圈體至少執行一次。do-while迴圈結構流程圖如下圖所示。

    

  Tip:while與do-while的區別在於,while迴圈中的迴圈體可能一次也不執行,而do-while迴圈中的迴圈體至少執行一次。

  3、for迴圈

    語法結構:

      for(初始表示式;布林表示式;迭代因子){

        迴圈體;

      }

    for迴圈語句是支援迭代的一種通用結構,是最有效、最靈活的迴圈結構。for迴圈在第一次反覆之前要進行初始化,即執行初始表示式;隨後,對布林表示式進行判定,若判定結果為true,則執行迴圈體,否則,終止迴圈;最後在每一次反覆的時候,進行某種形式的“步進”,即執行迭代因子。

    初始化部分設定迴圈變數的初值。

    條件判斷部分為任意布林表示式。

    迭代因子控制迴圈變數的增減for迴圈在執行條件判定後,先執行的迴圈體部分,再執行步進。

    for迴圈結構的流程圖如下圖所示。

    

    注意:

      1、無論在初始化還是在步進部分,語句都是順序執行的。

      2、儘管初始化部分可設定任意數量的定義,但都屬於同一型別。

      3、約定:只在for語句的控制表示式中寫入與迴圈變數初始化,條件判斷和迭代因子相關的表示式。

      4、初始化部分、條件判斷部分和迭代因子可以為空語句,但必須以“;”分開。

      5、編譯器將while(true)與for(;;)看作同一回事,都指的是無限迴圈。在for語句的初始化部分宣告的變數,其作用域為整個for迴圈體,不能在迴圈外部使用該變數。

break語句和continue語句

  在任何迴圈語句的主體部分,均可用break控制迴圈的流程。break用於強行退出迴圈,不執行迴圈中剩餘的語句。

  continue語句用在迴圈語句體中,用於終止某次迴圈過程,即跳過迴圈體中尚未執行的語句,接著進行下一次是否執行迴圈的判定。

  注意:

    1、continue用在while,do-while中,continue語句立刻跳到迴圈首部,越過了當前迴圈的其餘部分。

    2、continue用在for迴圈中,跳到for迴圈的迭代因子部分。

帶標籤的break語句和continue語句

  goto關鍵字很早就在程式設計語言中出現。儘管goto仍是Java的一個保留字,但並未在Java語言中得到正式使用;Java沒有goto語句。然而,在break和continue這兩個關鍵字的身上,我們仍然能看出一些goto的影子---帶標籤的break和continue。

  “標籤”是指後面跟一個冒號的識別符號,例如:“label:”。對Java來說唯一用到標籤的地方是在迴圈語句之前。而在迴圈之前設定標籤的唯一理由是:我們希望在其中巢狀另一個迴圈,由於break和continue關鍵字通常只中斷當前迴圈,但若隨同標籤使用,它們就會中斷到存在標籤的地方。

  在“goto有害”論中,最有問題的就是標籤,而非goto,隨著標籤在一個程式裡數量的增多,產生錯誤的機會也越來越多。但Java標籤不會造成這方面的問題,因為它們的活動場所已被限死,不可通過特別的方式到處傳遞程式的控制權。由此也引出了一個有趣的問題:通過限制語句的能力,反而能使一項語言特性更加有用。

 1 //控制巢狀迴圈跳轉(列印101-150之間所有的質數)
 2 public class Test18{
 3     public static void main(String args[]){
 4         outer:for(int i=101;i<150;i++){
 5             for(int j=2;j<i/2;j++){
 6                 if(i%j==0){
 7                     continue outer;
 8                 }
 9             }
10             System.out.print(i+"");
11         }
12     }
13 }

執行結果:

方法

  方法(method)就是一段用來完成特定功能的程式碼片段,類似於其它語言的函式(function)。方法用於定義該類或該類的例項的行為特徵和功能實現。方法是類和物件行為特徵的抽象。方法很類似於面向過程中的函式。面向過程中,函式是最基本單位,整個程式由一個個函式呼叫組成。面向物件中,整個程式的基本單位是類,方法是從屬於類和物件的。

  方法宣告格式:

    [修飾符1 修飾符2...] 返回值型別 方法名(形式引數列表){

      Java語句;

      .........

    }

  方法的呼叫方式:

    物件名.方法名(實參列表)

  方法的詳細說明:

    形式引數:在方法宣告時用於接收外界傳入的資料。

    實參:呼叫方法時實際傳給方法的資料。

    返回值:方法在執行完畢後返還給呼叫它的環境的資料。

    返回值型別:事先約定的返回值的資料型別,如無返回值,必須指定為void。

    注意:    

      1、實參的數目、資料型別和次序必須和所呼叫的方法宣告的形式引數列表匹配。

      2、return語句終止方法的執行並指定要返回的資料。

      3、Java中進行方法呼叫中傳遞引數時,遵循值傳遞的原則(傳遞的都是資料的副本):基本型別傳遞的是該資料值的copy值。引用型別傳遞的是該物件引用的copy值,但指向的是同一個物件。

方法的過載(overload)

  方法的過載是指一個類中可以定義多個方法名相同,但引數不同的方法。呼叫時,會根據不同的引數自動匹配對應的方法。

  Tip:過載的方法,實際是完全不同的方法,只是名稱相同而已!

  構成方法過載的條件:

    1、不同的含義:形參型別、形參個數、形參順序不同。

    2、只有返回值不同不構成方法的過載如:inta(Stringstr){}與voida(Stringstr){}不構成方法過載。

    3、只有形參的名稱不同,不構成方法的過載如:inta(Stringstr){}與inta(Strings){}不構成方法過載。

遞迴結構

  遞迴是一種常見的解決問題的方法,即把問題逐漸簡單化。遞迴的基本思想就是“自己呼叫自己”,一個使用遞迴技術的方法將會直接或者間接的呼叫自己。

  利用遞迴可以用簡單的程式來解決一些複雜的問題。比如:斐波那契數列的計算、漢諾塔、快排等問題。

  遞迴結構包括兩個部分:

    定義遞迴頭:什麼時候不呼叫自身方法。如果沒有頭,將陷入死迴圈,也就是遞迴的結束條件。

    遞迴體:什麼時候需要呼叫自身方法。

  

 1 //使用遞迴求n!
 2 public class Test22{
 3     public static void main(String[] args){
 4          long d1=System.currentTimeMillis();
 5          System.out.printf("%d階乘的結果:%s%n",10,factorial(10));
 6          long d2=System.currentTimeMillis();
 7          System.out.printf("遞迴費時:%s%n",d2-d1);//耗時:32ms
 8     }
 9  
10     /*
11      *求階乘的方法
12      */
13     static long factorial(int n){
14          if(n==1){
15             //遞迴頭
16             return1;
17          }else{
18             //遞迴體
19             return n*factorial(n-1);//n!=n*(n-1)!
20          }
21     }
22 }
23     

  執行結果:

    

  遞迴的缺陷

    簡單的程式是遞迴的優點之一。但是遞迴呼叫會佔用大量的系統堆疊,記憶體耗用多,在遞迴呼叫層次多時速度要比迴圈慢的多,所以在使用遞迴時要慎重。

  注意:

    1、任何能用遞迴解決的問題也能使用迭代解決。當遞迴方法可以更加自然地反映問題,並且易於理解和除錯,並且不強調效率問題時,可以採用遞迴。

    2、在要求高效能的情況下儘量避免使用遞迴,遞迴呼叫既花時間又耗記憶體。