面試官:Java8 lambda 表達式 forEach 如何提前終止?
情景展示
forEach中的 continue
如上圖所示,我們想要終止 for 循環,使用 return。
執行結果如下:
forEach中的 continue
我們可以看到,只有趙六沒被打印出來,后續的數組元素依舊被執行了。
也就是說,關鍵字return,在這里執行的效果相當于普通 for 循環里的關鍵詞continue。
原因分析
我們知道,在普通 for 循環里面,想要提前結束(終止)循環體使用break。
結束本輪循環,進行下一輪循環使用continue。
另外,在普通 for 里,如果使用return,不僅強制結束 for 循環體,還會提前結束包含這個循環體的整個方法。
而在 Java8 中的 forEach() 中 break或continue是不被允許使用的,而return的意思也不是原來 return 代表的含義了。
我們來看看源碼:
forEach 源碼
forEach(),說到底是一個方法,而不是循環體,結束一個方法的執行用什么?當然是return啦。
java8 的 forEach()和 JavaScript 的 forEach() 用法是何其的相似。
Java 不是萬能的,不要再吐槽它垃圾了。
解決方案
方案一:使用原始的 foreach 循環
Java foreach 循環
使用過 eclipse 的老鐵們應該知道,當我們輸入:foreach,再按快捷鍵:Alt+/,就會出現 foreach 的代碼提示。
如上圖所示,這種格式的 for 循環才是真正意義上的 foreach 循環。
在 idea 中輸入,按照上述操作是不會有任何代碼提示的,那如何才能在 idea 中,調出來呢?
Java foreach 循環
for 循環可以提前終止。
方式一:break
foreach 循環 break
方式二:return (不推薦使用)
foreach 循環 return
方案二:拋出異常
我們知道,要想結束一個方法的執行,正常的邏輯是:使用 return。
但是,在實際運行中,往往有很多不突發情況導致代碼提前終止,比如:空指針異常,其實,我們也可以通過拋出假異常的方式來達到終止 forEach() 方法的目的。
forEach 拋出異常
如果覺得這種方式不友好,可以再包裝一層。
forEach 拋出異常進行終止
這樣,就完美了。
這里,需要注意的一點是:要確保你 forEach() 方法體內不能有其它代碼可能會拋出的異常與自己手動拋出并捕獲的異常一樣;
否則,當真正該因異常導致代碼終止的時候,因為咱們手動捕獲了并且沒做任何處理,豈不是搬起石頭砸自己的腳嗎?