if else 是我們寫代碼時,使用頻率最高的關鍵詞之一,然而有時過多的 if else 會讓我們感到想吃
![if-else“煩不煩”,讓代碼簡單、高效、優雅起來](http://p2.ttnews.xyz/loading.gif)
,而且閱讀起來比較困難,維護起來也比較困難,很容易出 Bug,如下圖
![if-else“煩不煩”,讓代碼簡單、高效、優雅起來](http://p2.ttnews.xyz/loading.gif)
怎麼才讓代碼簡單、高效、優雅起來。
1,提前 return,去除不必要的 else
優化前代碼:
<code>if (str.equals("java")) {
// 業務代碼 ! true;
} else {
return ;
}/<code>
優化後代碼:
<code>if (str.equals("java")) {
return ;
}
return false;/<code>
缺點:if else多的話,沒什麼大的效果
2,使用條件三目運算符
使用條件三目運算符可以簡化某些 if-else,使代碼更加簡潔,更具有可讀性。
優化前:
<code>int price ;
if(condition){
price = 80;
}else{
price = 100;
}/<code>
優化後:
<code>int price = condition?80:100;/<code>
缺點:正對只有if 和esle這種兩個選擇的時候,還可以,但是多了的話,寫三元表達式的話,理解起來就費力了,如下
<code>int price = (condition>0) ? ((condition<10)? 8 : 11) : ((condition>-10)? -8 : -11) ;/<code>
3,使用 Map
使用 Map 數組,把相關的判斷信息,定義為元素信息可以直接避免 if else 判斷,實現代碼如下。
優化前代碼:
<code>if (t == 1) {
type = "name";
} else if (t == 2) {
type = "id";
} else if (t == 3) {
type = "mobile";
}/<code>
我們先定義一個 Map 數組,把相關判斷信息存儲起來:
<code>Map<integer> typeMap = new HashMap<>();
typeMap.put(1, "name");
typeMap.put(2, "id");
typeMap.put(3, "mobile");/<integer>/<code>
之前的判斷語句可以使用以下一行代碼代替了:
<code>type = typeMap.get(ty);/<code>
4,使用枚舉
JDK 1.5 中引入了新的類型——枚舉(enum),我們使用它可以完成很多功能,例如下面這個。
優化前代碼:
<code>Integer typeId = 0;
String type = "Name";
if ("Name".equals(type)) {
typeId = 1;
} else if ("Age".equals(type)) {
typeId = 2;
} else if ("Address".equals(type)) {
typeId = 3;
}/<code>
優化時,我們先來定義一個枚舉:
<code>public enum TypeEnum {
Name(1), Age(2), Address(3);
public Integer typeId;
TypeEnum(Integer typeId) {
this.typeId = typeId;
}
}/<code>
有了枚舉之後,以上 if-else 邏輯分支,可以優化為一行代碼:
<code>typeId = TypeEnum.valueOf("Name").typeId;/<code>
缺點:能力在此,暫無發現
5,合併條件表達式
在項目中有些邏輯判斷是可以通過梳理和歸納,變更為更簡單易懂的邏輯判斷代碼,如下所示。
優化前代碼:
<code>String city = "西安";
String area = "029";
String province = "陝西";
if ("西安".equals(city)) {
return "xi'an";
}
if ("029".equals(area)) {
return "xi'an";
}
if ("陝西".equals(province)){
return "xi'an";
}/<code>
優化後代碼:
<code>if ("西安".equals(city) || "029".equals(area) || "陝西".equals(province)){
return "xi'an";
}/<code>
缺點:這種是對結果相同的做法合併,但是返回值不同,就傻了
6,使用 Optional
從 JDK 1.8 開始引入 Optional 類,在 JDK 9 時對 Optional 類進行了改進,增加了 ifPresentOrElse() 方法,我們可以藉助它,來消除 if else 的判斷,使用如下。
優化前代碼:
<code>String str = "java";
if (str == null) {
System.out.println("Null");
} else {
System.out.println(str);
}/<code>
優化後代碼:
<code>Optional<string> opt = Optional.of("java");
opt.ifPresentOrElse(v ->
System.out.println(v), () -> System.out.println("Null"));/<string>/<code>
缺點:對於大多使用JDK 1.8的公司來說,這個實現起來得改JDK版本,不切實際
7,策略模式+工廠方法消除 if else
假設需求為,根據不同勳章類型,處理相對應的勳章服務,優化前有以下代碼:
首先,我們把每個條件邏輯代碼塊,抽象成一個公共的接口,可以得到以下代碼:
<code>//勳章接口
public interface IMedalService {
void showMedal();
}/<code>
我們根據每個邏輯條件,定義相對應的策略實現類,可得以下代碼:
接下來,我們再定義策略工廠類,用來管理這些勳章實現策略類,如下:
使用了策略+工廠模式之後,代碼變得簡潔多了,如下:
缺點:要多寫較多代碼,而且要新建類等
8,選擇性的使用 switch
很多人都搞不懂 switch 和 if else 的使用場景,但在兩者都能使用的情況下,可以儘量使用 switch,因為 switch 在常量分支選擇時,switch 性能會比 if else 高。
if else 判斷代碼:
<code>if (cmd.equals("add")) {
result = n1 + n2;
} else if (cmd.equals("subtract")) {
result = n1 - n2;
} else if (cmd.equals("multiply")) {
result = n1 * n2;
} else if (cmd.equals("divide")) {
result = n1 / n2;
} else if (cmd.equals("modulo")) {
result = n1 % n2;
}/<code>
switch 代碼:
<code>switch (cmd) {
case "add":
result = n1 + n2;
break;
case "subtract":
result = n1 - n2;
break;
case "multiply":
result = n1 * n2;
break;
case "divide":
result = n1 / n2;
break;
case "modulo":
result = n1 % n2;
break;
}/<code>
在 Java 14 可使用 switch 代碼塊,實現代碼如下:
<code>// java 14
switch (cmd) {
case "add" -> {
result = n1 + n2;
}
case "subtract" -> {
result = n1 - n2;
}
case "multiply" -> {
result = n1 * n2;
}
case "divide" -> {
result = n1 / n2;
}
case "modulo" -> {
result = n1 % n2;
}
}/<code>
缺點:同級判斷情況多,看起來不優雅,而且縱深拉扯很長
總結:使用枚舉來清楚if else是比較合理,不過也需要因項目而定,拋磚引玉希望可以幫助和啟發到你。
閱讀更多 禿頭程序員兒 的文章