尽信书不如无书之获取枚举值代码优化
1 背景
實際開發(fā)中根據(jù)枚舉的某個屬性獲取枚舉值非常常見。
如定義一個枚舉:
@Getter public enum CoinEnum {PENNY(1), NICKEL(5), DIME(10), QUARTER(25);CoinEnum(int value) {this.value = value;}private final int value; }實際開發(fā)中經(jīng)常需要根據(jù) value 的值來獲取枚舉對象。
那么該怎么做呢?
?
?
2 編碼
2.1 很low的寫法
工作中會見到有采用 switch-case 或者 if-else 實現(xiàn)根據(jù)某個屬性獲取枚舉的方式。
類似下面的這種寫法:
public static CoinEnum getEnum(int value) {switch (value) {case 1:return PENNY;case 5:return NICKEL;case 10:return DIME;case 25:return QUARTER;default:return null;} }這種寫法最大的問題是如果枚舉常量新增、刪除、修改等都需要對該函數(shù)進行對應的修改,耦合非常高。
不符合開閉原則(開閉原則:對拓展開放,對修改關(guān)閉)。
另外如果枚舉常量較多,很容易映射錯誤,后期很難維護。
?
2.2 改進
我們可以采用枚舉類的 values 靜態(tài)函數(shù)獲取枚舉數(shù)組進行匹配,寫出一個改進版本的代碼:
public static CoinEnum getEnum(int value) {for (CoinEnum coinEnum : CoinEnum.values()) {if (coinEnum.value == value) {return coinEnum;}}return null; }?
通過這種改進,后面需要對枚舉常量進行修改,該函數(shù)不需要改動,顯然比之前好了很多。
這種寫法在工作中也很常見。
那么是否還有改進空間呢?
這種寫法雖然挺不錯,但是每次獲取枚舉對象都要遍歷一次枚舉數(shù)組,時間復雜度是O(n)。
降低時間復雜度該怎么做?一個常見的思路就是空間換時間。
?
2.3 再次優(yōu)化
因此可以先用map緩存,使用時直接從map中取值。
可以這么優(yōu)化:
@Getter public enum CoinEnum {PENNY(1), NICKEL(5), DIME(10), QUARTER(25);CoinEnum(int value) {this.value = value;}private final int value;public int value() {return value;}private static final Map<Integer, CoinEnum> cache = new HashMap<>();static {for (CoinEnum coinEnum : CoinEnum.values()) {cache.put(coinEnum.getValue(), coinEnum);}}public static CoinEnum getEnum(int value) {return cache.getOrDefault(value, null);} }通過上面的優(yōu)化,使用時時間復雜度為 O(1),性能有所提升。
實際開發(fā)中能采用這種寫法的同學都不太多。
主要原因是網(wǎng)上類似的文章不多,這也是很多總愛百度解決問題而不是思考來解決問題的同學進步不大的重要原因。
?
2.4 學無止境
通過上面兩次優(yōu)化,代碼的耦合降低了,性能提高了。
所以,可以完美收工了?
NO...
2.3 給出的代碼還存在一些問題:
-
每個枚舉類中都需要編寫類似的代碼,很繁瑣。
-
引入提供上述工具的很多枚舉類,如果僅使用枚舉常量,也會觸發(fā)靜態(tài)代碼塊的執(zhí)行。
還有沒有更優(yōu)雅的方案呢?
希望大家可以思考一下,給出自己的解決方案。
具體解決方案參見《阿里巴巴Java開發(fā)手冊》詳解專欄的第 10 節(jié) 枚舉類的正確學習方式
?
3 總結(jié)
既然選擇編程這條路,希望大家在提問之前,在百度之前,一定要先有自己的思考。
校招和社招時,很多大公司的面經(jīng)非常吸引人,但是對大多數(shù)人幫助不大。是因為很多面經(jīng)只有題目沒有答案,好多人會搜索各種答案來背誦,然而很多所謂的標準答案都沒有揭露問題的本質(zhì),都是不完整的,也不是最佳答案。
盡信書不如無書,希望大家在讀書、看博客、看專欄等過程中更重視對問題的思考,對方法的學習,而是記憶具體知識點。俗話說“授人以魚不如授人以漁”,希望本文能夠啟發(fā)更多的朋友意識到思考和方法的重要性。
?
----------
如果你覺得本文對你有幫助,歡迎點贊、評論、轉(zhuǎn)發(fā)(注明出處)、關(guān)注,你的支持是我創(chuàng)作的最大動力。
總結(jié)
以上是生活随笔為你收集整理的尽信书不如无书之获取枚举值代码优化的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 群体智能:新一代AI的重要方向
- 下一篇: 很好的源码软件列表,有助于学习提高 (Z