if-else和三目運算子 ? : 的對比
阿新 • • 發佈:2020-07-10
今天的地鐵思考讓我想起一個之前學C語言的時候一直沒有驗證的事情:既生瑜何生亮?
- 平時寫程式碼的時候,似乎並沒有太多的關注我應該選用什麼條件判斷語句,感覺判斷條件或者兩條支路語句複雜就本能地if-else。
遇到一些數值,字元的按條件賦值輸出,就感覺if-else與這些簡短語句氣質不符,於是就用了三目運算子,使程式碼更簡潔舒服。那麼為什麼有了if-else還要用?:呢,只是為了程式碼更簡潔嗎,還是有什麼不為人知的祕密[/嘿嘿] - 我打算稍稍探尋一下,從兩個方面來聊聊:效率和三目運算子的表示式特性
關於執行效率
- 我在網上一直沒有找到可靠的說辭或指南,有的說三目運算子效率高,還有的說一樣的,所以我來測測(測試環境可能由於我的電腦效能,給定引數原因,不能得出確切的結論,僅供參考)
- if-else
public static void main(String[] args) { int num=1000; System.out.println("if-else 執行時間:"); long totalTime=0L; for (int i = 1; i <=10 ; i++) { long startTime = System.nanoTime(); if (num>500&&num%3!=0&&num/10==100){ num=1001; }else{ num=0; } long endTime = System.nanoTime(); long result = endTime - startTime; totalTime+=result; System.out.println("第"+i+"次: " + result + " 納秒"); } System.out.println("平均時間為:"+totalTime/10+"納秒"); }
-
執行結果:
-
三目運算子 ? :
public static void main(String[] args) { int num = 1000; System.out.println("? : 執行時間:"); long totalTime = 0L; for (int i = 1; i <= 10; i++) { long startTime = System.nanoTime(); num = num > 500 && num % 3 != 0 && num / 10 == 100 ? 1001 : 0; long endTime = System.nanoTime(); long result = endTime - startTime; totalTime += result; System.out.println("第" + i + "次: " + result + " 納秒"); } System.out.println("平均時間為:" + totalTime / 10 + "納秒"); }
- 執行結果:
- 從結論上來看,平均執行時間並沒有太大差距,畢竟這裡是以納秒為單位,所以,暫且以為
? :
僅僅是簡化程式碼的吧 -
如果哪位大佬有專業的權威的見解,請一定來“拍一拍”我,讓我的石頭落下。
表示式特性(BNP : binary numeric promotion)
-
二進位制數值提升
- 在三目運算子中的第二和第三表達式的型別依據數值範圍大的那個,將一個小數值的類型範圍擴大,比如16位提升到32位,32位到64位,直觀一點就是short提升到int,int提升到long,不同型別之間也可以提升,但是不一定是往兩個其中的一個走,也有short和char,最終表示式是int的情況。 -
舉幾個栗子就比較清楚了
- 1,引數是int和byte,但是整個表示式的型別卻是int
- 2,引數:int,char 表示式型別:int ![](https://img2020.cnblogs.com/blog/1900950/202007/1900950-20200710014429504-750530626.png) - 3,引數:short,char 表示式型別:int ![](https://img2020.cnblogs.com/blog/1900950/202007/1900950-20200710014735763-1827387039.png) - 4,引數:int,float 表示式型別:float (如果位元組數相同,會提升到浮點數) ![](https://img2020.cnblogs.com/blog/1900950/202007/1900950-20200710014805770-916117378.png) - 5,引數:int,long 表示式型別:long ![](https://img2020.cnblogs.com/blog/1900950/202007/1900950-20200710014944472-1952654095.png) - 6,引數:long,double 表示式型別:double (如果位元組數相同,會提升到浮點數) ![](https://img2020.cnblogs.com/blog/1900950/202007/1900950-20200710015004272-720659868.png) - 7,同上的包裝類,包裝類在運算時自動拆箱,和基本資料型別結果無異 ![](https://img2020.cnblogs.com/blog/1900950/202007/1900950-20200710015130391-625091652.png) - 8,更具體一點 ``` int number = 1000; System.out.println(number<0?10.0:9); ``` console: ![](https://img2020.cnblogs.com/blog/1900950/202007/1900950-20200710020252217-1846785275.png)
總的來看,if-else和三目運算子並沒有在今天分出勝負,我們依然可以按照之前的習慣寫程式碼,只是讓我們之後寫程式碼的不用再猶豫和糾結用什麼好,不用再想起他們倆之間的糾葛。在實際生產環境中按照各自團隊規範來就好。這些也是最近才發現的,雖然感覺很少用到,但這不是目的。我們遇到的東西那麼多,不會每樣都能用到你的程式裡,只是為了在下次遇到此類問題Bug時,能夠遊刃有餘,這就是我們程式設計師鴨,突然感覺這篇文章啥也沒做,但是卻也不是啥也沒做,哈哈奇怪咧。
- 參考文件:Java語言規範--https://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-ConditionalExpression
至此,若有紕漏,望各位不吝賜教