昨日書いた、
oboe2uran.hatenablog.com
の続きです。
昨日書いたもの。。。
public static <T> UnaryOperator<List<T>> listAddReturn(T t){ return l->{ l.add(t); return l; }; }
Map<String, List<String>> map = new HashMap<>(); map.put("a", Optional.ofNullable(map.get("a")) .map(list->listAddReturn("A").apply(list)) .orElse(listAddReturn("A").apply(new ArrayList<String>())) );
これでは、listAddReturn を2回書いてしまいます。そこでとりあえず、、、
public static <K, V> void pushMap(Map<K, V> map, K k, UnaryOperator<V> u, Supplier<V> s){ map.put(k, Optional.ofNullable(map.get(k)) .map(e->u.apply(e)) .orElse(u.apply(s.get())) ); }
単に Supplier を指定するようにしただけなので、以下のように書くことになるのですが、
毎回、Supplier を指定するのもどうかと思います。でもこれはこれで汎用性がありそうです。
pushMap(map, "b", listAddReturn("B"), ()->new ArrayList<String>());
Supplier 指定をしなくて済むものを用意します。
(上で書いた listAddReturn を使います)
List 限定になります。
public static <K, V> void pushMapList(Map<K, List<V>> map, K k, V v){ map.put(k, Optional.ofNullable(map.get(k)) .map(e->listAddReturn(v).apply(e)) .orElse( new Function<V, List<V>>(){ @Override public List<V> apply(V u){ List<V> l = new ArrayList<V>(); l.add(u); return l; } }.apply(v) ) ); }
↑↑↑
なんか、短絡的というか、動物的なコーディングですが、、
pushMapList(map, "c", "C" );
これで、
Map<String, List<String>> map;
に対して、
key が存在しなければ、List 生成して List に add してマップ PUSH
key が存在すれば、map から GETした List に add してマップ PUSH
というのが、少ない行で書けます。
メソッド名が、そういうことを処理するという表現であれば、そんなに可読性が悪くないと考えます。
。。。もうちょっと良い名前を考えよう。。。