2016-05-09 8 views
2

Map<Key, Collection<Value>> myMapとキーに関連付けられたコレクションから値を削除するメソッドがあるとします。値を削除すると、空のコレクションを離れた場合、我々は、マップ内のkeyエントリを取り除きたいと思います:値が空の場合にキーを削除する

List<Value> removeValue(Key key, Value value) { 
    List<Value> v = myMap.get(key); 
    if (v != null) { 
     v.remove(value); 
     if (v.isEmpty()) 
      myMap.remove(key); 
    } 
    return v; 
} 

ワンライナーまたは短い方法で説明した動作を実現するために、任意のJava 8の方法はあります?

+1

すぐに気になることはありません。これは、http://codereview.stackexchange.com/に適しているかもしれません。 – markspace

+0

元の方法は間違っているようですが、とにかく冗長すぎるようではありません。 – manouti

+1

'if(v.size()== 1)myMap.remove(key);'が間違っています。リストに値が含まれていない場合はどうなりますか? – smac89

答えて

6

あなたはこのためにcomputeIfPresentを使用することができます。その値はnullでない場合(それはnullcomputeIfPresent戻ってすぐにnullある場合)

static <K, V> List<V> removeValue(K key, V value, Map<K, List<V>> map){ 
    return map.computeIfPresent(key, (k, l) -> l.remove(value) && l.isEmpty() ? null : l); 
} 

computeIfPresentは、キーとマップ内の現在の値にBiFunctionを適用し、戻り値がnullではない場合は、の戻り値に値を設定するか、戻り値がnullの場合はキーをマップから削除し、最後に新しい値を返します。

removefalseを返すため、これは問題の方法とは少し異なる動作をします。既に空のListはマップから削除されません。既に空のListを削除する場合は、l.isEmpty() || (l.remove(value) && l.isEmpty())を使用できます。

+0

ありがとうございました!奇妙なことに、第二の形式(私が正確に探していたもの)は第一のものよりも良く理解しています。また、要素を置くために同様のことができますか?私は 'computeIfPresent'と' computeIfAbsent'の両方を使うべきだと私は思っています。それとも一列にすることもできますか? – dabadaba

+1

@dabadabaもしリストが存在しなければそれを作成したいなら 'map.computeIfAbsent(key、k - >新しいArrayList <>())を使うことができます。add(v)' – Alex

+0

@dabadaba ['compute'](https://docs.oracle.com/javase/8/docs/api/java/util/Map.html#compute-K-java.util.function.BiFunction-)を使ってくださいそれはそれが「ヌル」であることが大丈夫です。 'myMap.compute(key、(k、l) - > {if(l == null)l =新しいArrayList <>(); l.add(値); return l;});' – 4castle

関連する問題