原創:扣釘日記(微信公眾號ID:codelogs),歡迎分享,轉載請保留出處。 簡介 java8之後,常用的Map介面中添加了一些非常實用的函數,可以大大簡化一些特定場景的代碼編寫,提升代碼可讀性,一起來看看吧。 computeIfAbsent函數 比如,很多時候我們需要對數據進行分組,變成Map< ...
原創:扣釘日記(微信公眾號ID:codelogs),歡迎分享,轉載請保留出處。
簡介
java8之後,常用的Map介面中添加了一些非常實用的函數,可以大大簡化一些特定場景的代碼編寫,提升代碼可讀性,一起來看看吧。
computeIfAbsent函數
比如,很多時候我們需要對數據進行分組,變成Map<Integer, List<?>>
的形式,在java8之前,一般如下實現:
List<Payment> payments = getPayments();
Map<Integer, List<Payment>> paymentByTypeMap = new HashMap<>();
for(Payment payment : payments){
if(!paymentByTypeMap.containsKey(payment.getPayTypeId())){
paymentByTypeMap.put(payment.getPayTypeId(), new ArrayList<>());
}
paymentByTypeMap.get(payment.getPayTypeId())
.add(payment);
}
可以發現僅僅做一個分組操作,代碼卻需要考慮得比較細緻,在Map中無相應值時需要先塞一個空List進去。
但如果使用java8提供的computeIfAbsent
方法,代碼則會簡化很多,如下:
List<Payment> payments = getPayments();
Map<Integer, List<Payment>> paymentByTypeMap = new HashMap<>();
for(Payment payment : payments){
paymentByTypeMap.computeIfAbsent(payment.getPayTypeId(), k -> new ArrayList<>())
.add(payment);
}
computeIfAbsent
方法的邏輯是,如果map中沒有(Absent)相應的key,則執行lambda表達式生成一個預設值並放入map中並返回,否則返回map中已有的值。
帶預設值Map
由於這種需要預設值的Map太常用了,我一般會封裝一個工具類出來使用,如下:
public class DefaultHashMap<K, V> extends HashMap<K, V> {
Function<K, V> function;
public DefaultHashMap(Supplier<V> supplier) {
this.function = k -> supplier.get();
}
@Override
@SuppressWarnings("unchecked")
public V get(Object key) {
return super.computeIfAbsent((K) key, this.function);
}
}
然後再這麼使用,如下:
List<Payment> payments = getPayments();
Map<Integer, List<Payment>> paymentByTypeMap = new DefaultHashMap<>(ArrayList::new);
for(Payment payment : payments){
paymentByTypeMap.get(payment.getPayTypeId())
.add(payment);
}
呵呵,這玩得有點像python的defaultdict(list)
了