java 的流程控制
控制代碼執行的一個路徑、方向。
三類:
順序執行:從上到下依次執行代碼。
分支選擇:根據條件 來 選擇執行某些代碼,跳過某些代碼。
循環:某些代碼反覆的被執行。
if 選擇語句
單分支選擇:
語法:
if(條件表達式){
//任意行java 代碼
}
//java 後續代碼
解釋:
if 是關鍵字 如果 的意思。
條件表達式:必須是一個返回值爲 boolean 類型的表達式。
往往是關係表達式 邏輯 表達式。
{}:if 代碼塊。看做一個執行的整體。
執行過程:
1:如果 條件表達式成立 返回值 爲 true,那麼就執行 if 代碼塊中的所有的代碼。
2:如果條件表達式不成立 返回值 爲false,那麼就跳過if 代碼塊中的所有的代碼,執行java 後續的代碼內容。
注意:
如果 if 代碼塊 只有一條語句,那麼大括號可以省略。if 控制這一條代碼的執行與否。
條件表達式的小括號的後面,千萬不要加分號,加上分號之後,條件控制的就是分號是否執行。和 後面的代碼塊 沒有一點關係了。
if-else:雙分支選擇語
語法:
if(條件表達式){
//if 代碼塊
}else;{
//else 代碼塊
}
//後續代碼
解釋:
else:java 關鍵字 否則的意思
執行過程:
1:如果 if 的條件成立 條件表達式的返回值 爲 true。那麼 執行 if 代碼塊的內容。執行完 if 代碼塊的內容後,直接跳過else 代碼塊。執行後續代碼。
2:如果 if 條件不成立 false。那麼跳過 if 代碼塊 的內容,直接執行else 的代碼塊,執行完畢後,執行 後續代碼。
注意:
1:if 和 else 代碼塊 必須執行且只能執行一個代碼塊。
2:if 代碼塊 和 else 代碼塊 ,任意一個代碼塊 如果只有一條語句,大括號可以省略。
3:if 和 else 條件的後面 不能添加 ;
4: if 語句可以單獨存在,但是else 是不可以單獨存在的。else 必須和 某一個if 配對。
多分支:if else if else
語法:
if(條件-1){
//代碼塊-1
}else if(條件-2){
//代碼塊-2
}else if(條件-2){
//代碼塊-3
}else if(條件-2){
//代碼塊-4
}.... //任意個else if
else{
//代碼塊-n
}
//後續代碼塊
執行過程:
1:先判斷條件-1,成立 true,執行代碼塊-1 然後跳過後續的所有的 代碼塊-n,執行後續代碼。
2:如果條件-1 不成立 false,跳過 代碼塊-1 繼續 判斷代碼塊-2 跳過後續的所有 代碼塊-n ,執行後續代碼。如果不成立 false,跳過代碼塊-2 繼續判斷
條件-3 依次類推。
3:簡單概述:if 後面的條件,如果有一個成立的,那麼就執行 對應的代碼塊。其他的代碼塊 都不執行。
4:如果所有的條件 都不成立 那麼 執行 最後的 else 代碼塊-n。
注意的問題:
1:所有的代碼塊-1 到 -n,必須執行且僅執行一個。條件互斥的代碼塊。
2:else 的數量必須小於等於 if 的個數。最後的else 可以沒有。如果最後的else 沒有,那麼可能沒有一個代碼塊-n 被執行,條件都沒有成立。
3:else 和它前面的最近的if 配對。
switch:多分支選擇語句
switch:開關。
語法:
比較多見的形式:
switch(表達式-1){
case 常量表達式:
//任意行的java 代碼
break;
case 常量表達式:
//任意行的java 代碼
break;
case 常量表達式:
//任意行的java 代碼
break;
...
default:
//任意行的java 代碼
break;
}
解釋:
1:表達式-1: 必須是一個變量,或者是變量表達式。
表達式的返回值類型只能是:char 、byte、short、int、Enum(jdk1.5)、String(jdk1.7).
2:case 後的表達式:必須是常量 或者是 常量表達式
3:default:是關鍵字 ,默認的意思。
執行過程:
1:首先計算表達式-1 的返回值。
2:用 表達式-1 的返回值 依次 和 每一個case 後的表達式的返回值 進行比較,,如果兩個值相等。那麼就執行 case 和 break 之間的代碼。
執行到break 結束整個switch 語句。
3:如果表達式-1 的返回值 和 每一個case 後的值 都不相同,那麼就執行 default 後的java 代碼。遇到break 結束 switch 語句。
注意:
1:表達式-1 和 所有的case 後的表達式的返回值的類型要兼容。
2:每一個case 後的表達式的返回值 都必須和其他的case 是不同的。
3:default 和 其後的 break; 語句 是可以沒有。如果沒有,那麼可以一個分支都不執行。
4:每一個case 後的 break ,都是可以沒有的。如果case 沒有對應的break ,那麼執行的效果是??後面的case 語句,被當作了普通的java 代碼被順序執行。
直到遇到了一個break 語句,才能 結束整個switch 語句。
5:break 是打斷的意思。在switch 語句中的作用:就是爲了結束switch 語句。
循環
循環的分類:
四種:
while 循環
do-while 循環
for 循環
for-each 循環 專門針對容器的循環。 jdk1.5
以後會新加Java8函數編程的筆記
while 循環:
語法:
while(循環條件){
//循環體---需要反覆執行的java 代碼。
}
//後續代碼
解釋:
1:循環條件: 必須是一個boolean 表達式 。返回一個 布爾值。根據該布爾值的結果來判斷是否需要執行 某些代碼。
2:{}:中的內容 稱之爲 循環體 :需要反覆執行的某些代碼。
執行過程:
1:先判斷 循環條件是否成立--true,如果是true 那麼就 執行 循環體中 的代碼。循環體執行完畢之後,繼續判斷循環條件,成立,繼續執行循環體。
2:反覆判斷,執行的過程。直到 判斷到 循環條件不成立的時候--false。那麼就直接結束整個循環。執行後續的代碼。
注意:
1: 如果 循環體的內容 只有一條java 語句,那麼 循環體的大括號 可以沒有。如果循環體是多條語句,那麼必須使用大括號括起來。
2:千萬不要在 循環條件 後添加分號。
3:通常會在循環體中對 循環條件進行改變,以達到在適當的時候結束循環。
4:while 循環有可能循環體一次都不執行。一開始 循環條件不成立,那麼循環體就一次都不執行。
循環的構成:
1:循環體
2:循環的控制部分:
1:循環控制初始化
2:循環條件
3:循環迭代部分
do-while
語法:
do{
//循環體
}while(循環條件);
執行過程:
上來就先執行一次循環體,然後再進行循環條件的判斷。成立-true,繼續執行循環體,不成立,false 直接結束循環。
注意:
1:循環體是一句java 代碼,大括號可以省略。
2:循環條件後的分號 ; 必須存在。
3:do-while 至少會執行一次循環。while 有可能一次都不執行循環體。
使用的環境:
如果循環條件判斷要依賴於循環體得到的結果,那麼可以考慮使用 do-while
但是仍然可以使用while 替代 do-while 在循環條件之前先得到一個結果。然後再判斷。
for 循環
語法:
for(循環條件初始化 1 ; 循環條件 2 ; 迭代 3 ){
//循環體 4
}
解釋:
1:for 的小括號中 由 2個 分號 切分成了3部分。
執行過程:
1:循環條件初始化 執行 且僅執行一次。
2:判斷循環條件是否成立,成立,那麼執行 循環體。然後執行迭代部分,然後再判斷循環條件。
3:一旦循環條件不成立,那麼立即結束循環。
1,2,4,3,2,4,3,2,4,3,2(不成立了)結束。
注意事項:
1:循環條件初始化 執行 且僅執行一次。
2:小括號中的兩個分號是必不可少的。其他的三部分從語法層面上來講,都可以沒有。
3:如果循環條件這部分沒有,那就代表循環條件永遠成立。
4:如果初始化部分需要初始化多個變量,那麼可以使用逗號分割,包括迭代部分亦然。
5:在 for 循環的 小括號中定義的變量,只能在for 循環中使用。
循環的選擇
do–while : 不考慮了
while:只知道循環的條件,不知道循環具體的次數,可以考慮是用while 循環。
for:知道循環具體的次數,使用 for 就可以了。
break,continue
break: 打斷的意思。
1:就是在switch 語句中使用,和case 配對,
作用:用來結束switch 語句。
2:在 循環體 中使用。
作用:用來結束循環。(只能結束一層循環)。
//水仙花數:在 100-999 之間有幾個這樣的數 : 該三位數的每一位的 三次冪 之和 等於該數自身 求這幾個數是什麼??
public class TestLoop2{
public static void main(String[] args){
int unit = 0;
int decade = 0;
int hundred = 0;
int i = 999;
for(;;){
unit = i%10;
decade = i/10%10;
hundred = i/100;
if(unit * unit * unit + decade * decade * decade + hundred * hundred * hundred == i){
System.out.println(i);
}
//最後一個100 判斷完畢之後,結束
if(i == 100)break;
i--;
}
}
}
continue:java 關鍵字 繼續的意思
如何使用:只能在循環體中使用。
作用:當continue被執行的時候。循環體中後續的內容將被跳過,進行下一次的循環。
while 和 do while 循環,執行到了continue ,那麼直接跳到循環條件判斷處去判斷執行,進行下一次的循環。
for 循環,跳到 迭代處去執行,然後再進行條件的判斷。
標號
解釋:
break 和 continue 後都可以跟標號
可以通過break 後面跟標號,實現跳出標號對應的那一層循環。
可以通過continue 後面跟標號,實現 跳到對應層的循環的迭代處(for),while do-while 循環條件判斷處。
//標號
public class TestLabel{
public static void main(String[] args){
//外層循環控制行數
//定義標號
label1 : for(int i = 1;i<=9;i++){
//內層循環控制一行的顯式內容
for(int j = 1;j<=i; j++){
int num = j*i;
System.out.print(j+"*"+i+"="+num+"; ");
if(j == 7)break label1;
}
System.out.println();
}
}
}
遇到了再補充,先佔個位置
2.foreach遍歷
jdk1.5 版本之後纔有的。
作用:用來遍歷容器的。可以用來遍歷數組。只能用來遍歷元素,不能用來修改元素的值。
使用增強的for 循環 訪問的數組的數據,都是源數組的元素的拷貝。
for(String x : array){
}
當需要以其他順序遍歷數組或改變數組中的元素時,還是必須使用下標變量。
總結:
增強的for 循環 。其實沒有增強,反而功能被削弱了!
for-each 只能用來遍歷數組,不能在循環中修改元素的值??。
語法相對簡單了一點。
詳解:
可以改變對象的值,但是不能刪除或添加對象,也不可以改變變量(比如int a)的值,就算用集合存變量依舊不能。
在foreach循環裏remove(0)或add(xxx),那就會報錯,是因爲foreach會默認轉換成iterator模式,在迭代器的next方法中調用了checkForComodification方法,會進行判斷是否迭代中進行了修改,會拋出異常。
主要是用來實現fail-fast機制
有兩個線程(線程A,線程B),其中線程A負責遍歷list、線程B修改list。
-線程A在遍歷list過程的某個時候(此時expectedModCount = modCount=N),線程啓動,
同時線程B增加一個元素,這是modCount的值發生改變(modCount + 1 = N + 1)。 線程A繼續遍歷執行next方法時,
通告checkForComodification方法發現expectedModCount = N , 而modCount = N + 1,兩者不等,
這時就拋出ConcurrentModificationException 異常,從而產生fail-fast機制。
/**
* 在對一個集合對象進行跌代操作的同時,並不限制對集合對象的元素進行操作
* 這些操作包括一些可能引起跌代錯誤的add()或remove()等危險操作。
* 在AbstractList中,使用了一個簡單的機制來規避這些風險。
* 這就是modCount和expectedModCount的作用所在
*/
final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
————————————————
原文鏈接:https://blog.csdn.net/weixin_40254498/article/details/81386920
3.迭代器遍歷
List list = Arrays.asList(array);
4.stream遍歷
Arrays.asList(array).stream().forEach(x -> System.out.println(x));
也可以這樣寫:
Arrays.asList(array).stream().forEach(System.out::println);
方法的必要性:
1:通過方法可以實現重複代碼的簡化,和代碼的複用。
2:將某些功能代碼封裝到一個方法的內部,實現了功能的模塊化,方便後期的維護和修改。
方法的定義:
語法:
[方法的修飾符 public static] 方法的返回類型 方法名(參數列表){
//方法體
}
1:[方法的修飾符 public static]:
可選的部分,不是必須的,目前就這麼用就ok了。
方法的修飾符分爲:可訪問控制符和非訪問控制符兩類(看Java關鍵字解析 還沒寫)
可訪問控制符有 4 種:
公共訪問控制符: public ;
私有訪問控制符: private ;
保護訪問控制符: protected ;
私有保護訪問控制符: private protected
非訪問控制符有 5 種:
抽象方法控制符: abstract ;
靜態方法控制符: static ;
最終方法控制符: final ;
本地方法控制符: native ;
同步方法控制符: synchronized
2:方法的返回類型:
可以是 void(空) || java 支持的任意類型.
代表着方法 執行完畢之後 是否會產生一個結果。
【1】一種方法只是實現了一段功能,不會得到一個結果。那麼該方法的返回類型 必須是void。
【2】一種方法,執行完畢之後希望得到一個結果數據。這個時候方法的返回類型就不能是void了。必須是的數據類型要與結果的數據類型兼容。
3:方法名:通過名字來訪問該方法的功能。還要通過名字來顯示該方法實現了什麼樣的功能。
方法名也是一類標識符。命名規範和局部變量一致,首字符小寫,遵循駝峯命名法。
4:參數列表:又稱爲形參列表。
表達的意思:在使用方法的時候,需要傳遞給方法的一些動態的數據,表達了方法在使用的時候的一種需求。
public static void printStarRect(int width) :在使用該方法的時候,需要給方法傳遞一個 int 類型的值。
參數列表的格式:
1:參數列表可以爲空。()
2: 需要傳遞的數據可以是任意個,類型也是任意類型。(數據類型 變量名1, 數據類型 變量名1, 數據類型 變量名1......)
5:方法體:功能實現的主體部分。
return:
如果方法的返回類型是 void。那麼可以在方法中 使用 [return;]
作用:直接結束方法。方法直接返回。
如果方法的返回類型 不是void ,那就是java支持的某種類型。那麼該方法必須 使用 return 後面跟着一個 想要得到的結果。
public static int max(int a,int b){
int max = a > b ? a : b;
return max;
}
6:把方法的名字 + 參數列表 組合 稱之爲 方法的簽名 signature。
在一個類的內部 方法的簽名 必須唯一。
7:方法的使用:
方法的調用 invoke
通過方法名 + 參數列表(實參列表);
8:若想使用方法定義的功能,那麼必須調用方法纔可以執行。必須直接的或者間接的在main方法中被調用。
方法只定義好了,不使用,是不會執行的。
內存圖
1:方法的調用,跳轉執行。
第一步,先進行參數的傳遞,將實際參數的值賦值給形式參數。參數的傳遞本質是一個複製的過程。形式參數就是一種局部變量參數,先對局部變量進行空間的分配。
方法調用完畢之後,系統會將該方法分配的所有局部變量的內存整體回收,棧幀
參數的傳遞的本質:就是開闢形參的內存空間,並將實際參數的值賦值給形式參數的過程。
所有對於形式參數的改變都是改變的 實際參數值的拷貝 不會影響實際參數原有的值。
注意問題:
1:方法不能被定義到任意的其他的方法的內部去。
2:所有的方法都必須在某一個類的內部。必須被最外層的大括號包圍。
3:如果想使用方法提供的功能。方法的調用。那麼該方法必須直接的或者間接的被 main 調用。
4:方法的調用的格式語法:方法名+參數列表(實參列表)。
5:定義方法的時候,方法體不要過長。(方法的功能要單一化)極限50行代碼,最好不要超過20行代碼。
方法的重載: overload
概念:在同一個類的內部,方法名字相同,參數列表不同,與返回類型無關 的方法,稱之爲 方法的重載。
方法名字相同:代表重載的方法實現的是類似的功能。
參數列表不同: 參數的個數不同、參數的類型不同、順序不同。
與返回類型無關:對於返回類型不是void 的方法,通常的用法是 使用該方法 參與某些計算的表達式。 但是也可以直接調用,而不參與任何的運算。與返回類型是void 的直接調用的方式,是有語義的衝突的。(保證方法的簽名 signature 唯一性)。
方法的重新寫
前提條件:存在繼承。在子類中重寫父類的方法。
==爲什麼需要重寫:子類對象覺得父類中繼承的方法不能滿足自身的需求了。需要重新定義該方法。就可以在子類中對父類中的被繼承的下來的方法進行重寫。 ==
面試題
1: 如何選擇if or switch
switch:只能用於等值比較的多分支選擇。
if-else if -else :既可以使用等值比較判斷,還可以進行不等值的比較的多分支選擇。
2:break和continue,return
break:結束當前循環,並推出循環體
break:在switch中,退出
continue:如果在雙重循環內循環中,結束當前層次的循環,後邊的代碼不執行,跳到外層循環條件判斷的地方,判斷是否進行下一次循環。
return:結束,如果有返回值,返回一個結果。