使用Java8的进来,这几个方法不香吗?
??
JDK8 應該是 Java 中最堅挺一個版本,這個版本新增很多特性,讓我們開發起來多了很多便利。
不過最近 Review 項目代碼的時候發現,雖然很多項目工程已經使用了 JDK8,但是工程代碼卻很少使用到 JDK8 新特性、新方法。
如果單從代碼正確性上來說,老方式寫法寫當然沒有什么問題,那唯一的缺點其實就是代碼行數比較多,比較繁瑣。
那同樣的需求,使用 JDK8 新方法,其實幾行代碼就可以搞定,這樣代碼就會變得非常簡潔。
今天就以三個比較常見的場景為例,教你幾招,使用 JDK8 Map新增的方法簡化代碼開發。
下面就來看看這次即將用到 Map幾個新方法:
預防空指針問題
日常開發中我們通常會從 Map獲取元素,然后進行相關的業務處理,示例代碼如下:
Map<String,?String>?map?=?new?HashMap(); map.put("公號",?"小黑十一點半"); map.put("主理人",?"樓下小黑哥"); //?可能存在?NPE?問題 System.out.println(map.get("支付").toUpperCase());如果就像示例代碼直接處理,一旦 Map中相應元素不存在,那么我們就會碰到空指針問題。
為了解決這個問題,通常我們可以先判斷一下元素是否為 null,如果不為 null,再做相應的業務處理。
//?第一種?if?判空 String?value?=?map.get("支付"); if?(!Objects.isNull(value))?{System.out.println(value.toUpperCase()); }這種方式唯一劣勢就是代碼處理上比較繁瑣,不是很簡潔。
所以針對這種情況,其實可以使用「條件運算符」,設置一個默認空值,從而避免后續處理發生空指針。
//?第一種?if?判空 String?value?=?map.get("支付"); //?第二種?條件運算符 value?=?Objects.isNull(value)???""?:?value;這種方式比較簡潔,所以日常開發中我比較喜歡用這種方式。
ps: 這里的前提,空字符串對于業務沒有特殊意義。如果存在特殊意義,那就不能使用這種方式了。
那如果使用 JDK8 ,其實就很方便了,我們就可以使用 Map#getOrDefault直接代替條件運算符。
//?等同于條件運算符的效果:Objects.isNull(value) ? ""?: value; String?value?=?map.getOrDefault("支付","");借助 Map#getOrDefault 一行代碼直接搞定,就是這么簡單。
如果你還在使用 JDK8 之前的版本,沒辦法使用這個方法。沒關系,我們可以借助 Apache 「Common-Lang3」 提供的工具類 MapUtils 避免空指針。
//?Apache?MapUtils String?value?=?MapUtils.getString(map,?"支付",?"");MapUtils這個工具類相對于Map#getOrDefault有一個好處,針對傳入 Map為 null 的情況,可以設置默認值。
假設我們是從 POJO對象獲取 Map 參數,這個時候為了防止空指針,我們就需要提前做一個空指針的判斷。
不過如果使用 MapUtils,那我們就不需要判斷是否為 null,方法內部已經封裝這個邏輯。
MapUtils.getString(pojo.getMap(),"支付",?"");巧用 computeIfAbsent
日常開發中,我們會碰到這類場景,需要一個鍵需要映射到多個值,這個時候我們可以使用 Map<K, List<V>>這個結構。
此時添加元素的時候,我們需要做一些判斷,當內部元素不存在時候主動創建一個集合對象,示例代碼如下:
Map<String,?List<String>>?map?=?new?HashMap();List<String>?classify?=?map.get("java框架"); if?(Objects.isNull(classify))?{classify?=?new?ArrayList<>();classify.add("Spring");map.put("java框架",?classify); }?else?{classify.add("Spring"); }上面的代碼比較繁瑣,到了 JDK8,Map新增一個 computeIfAbsent方法:
default?V?computeIfAbsent(K?key,Function<??super?K,???extends?V>?mappingFunction)?{如果 Map中 ?key 對應的 value 不存在,則會將 mappingFunction 計算產生的值作為保存為該 key 的 value,并且返回該值。否則不作任何計算,將會直接返回 ?key 對應的 value。
利用這個特性,我們可以直接使用 Map#computeIfAbsent一行代碼完成上面的場景,示例代碼如下:
map.computeIfAbsent("java框架",?key?->?new?ArrayList<>()).add("Spring");那其實 Map 中還有一個方法 putIfAbsent,功能跟 computeIfAbsent比較類似。
那剛開始使用的時候,誤以為可以使用 putIfAbsent完成上面的需求:
//?ERROR:會有?NPE?問題 map.putIfAbsent("java框架",?new?ArrayList<>()).add("Spring");那其實這是錯誤的,當 Map 中 key 對應 value 不存在的時候,putIfAbsent將會直接返回 null。
而 computeIfAbsent將會返回 mappingFunction計算之后的值,像上面的場景直接返回就是 new ArrayList。
這一點需要注意一下,切勿用錯方法,導致空指針。
最后針對上面這種一個鍵需要映射到多個值,其實還有一個更優秀的解決辦法,使用 Google Guava 提供的新集合類型 Multiset,以此快速完成一個鍵需要映射到多個值的場景。
示例代碼如下:
ArrayListMultimap<Object,?Object>?multiset=?ArrayListMultimap.create(); multiset.put("java框架","Spring"); multiset.put("java框架","Mybatis"); //?java框架--->Spring,Mybatis單詞統計
假設有如下需求,我們需要統計一段文字中相關單詞出現的次數。那實現方式其實很簡單,使用 Map存儲相關單詞的次數即可,示例代碼如下:
Map<String,?Integer>?countMap?=?new?HashMap(); Integer?count?=?countMap.get("java"); if?(Objects.isNull(count))?{countMap.put("java",?1); }?else?{countMap.put("java",?count++); }這類代碼是不是很熟悉?同樣比較繁瑣。
接下來我們可以使用 JDK8 Map 新增方法進行改造,這次使用上面用過的 getOrDefault 再加 put 方法快速解決,示例代碼如下:
//?getOrDefault Integer?count?=?countMap.getOrDefault("java",0); countMap.put("java",?count?+?1);那其實我們還有一種辦法,這次我們使用 Map#merge這個新方法,一句代碼完成上述需求,示例代碼如下:
countMap.merge("java",?1,?Integer::sum);說真的,剛看到 merge這個方法的時候還是有點懵,尤其后面直接使用 lambda 函數,讓人不是很好理解。
這里先將lambda 函數還原成正常類,給大家著重解釋一下這個方法:
countMap.merge("java",?1,?new?BiFunction<Integer,?Integer,?Integer>()?{@Overridepublic?Integer?apply(Integer?oldValue,?Integer?newValue)?{return?Integer.sum(oldValue,newValue);} });用上面代碼說明一下merge方法,如果 java這個值在 countMap中不存在,那么將會其對應的 value 設置為 1。
那如果 java 在 countMap 中存在,則會調用第三個參數 remappingFunction 函數方法進行計算。
remappingFunction 函數中,oldValue代表原先 countMap 中 java 的值,newValue代表我們設置第二個參數 「1」,這里我們將兩者相加,剛好完成累加的需求。
最后
這次主要從個人日常碰到三個場景出發,給大家對比了一下使用 JDK8 ?Map 新增方法只會,兩者代碼區別。
從上面可以很明顯看出,使用新增方法之后,我們可以用很少的代碼可以完成,整體看起來變得非常簡潔。
不過 JDK8 之后很多方法都會用到 lambda 函數,不熟悉的話,其實比較難以理解代碼。
不過也還好,我們只要在日常編碼過程中,刻意去練習使用,很快就能上手。
最后,JDK8 還有許多好用方法,刻意簡化代碼開發,你可以在留言區推薦幾個嗎?
有道無術,術可成;有術無道,止于術
歡迎大家關注Java之道公眾號
好文章,我在看??
總結
以上是生活随笔為你收集整理的使用Java8的进来,这几个方法不香吗?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: nginx的使用
- 下一篇: .NET 通用权限设计