2017-07-14 15 views
0

重複したキーが入力されても実際には2つの対応する値が一緒に追加された場合、値を置き換えないバージョンのHashMapを作成しようとしています。キー値は、追加が発生するようにタイプNumberでなければなりません。しかし、VNumberのタイプであること、または少なくともsuper.putを呼び出すまではそれがないことを理解していないようです。 VHashMapは、実際にVと同じではなく、extend Numberと宣言したものと同じです。パラメータ化されたコレクションを持つジェネリック?

ここでは何が起こっていますか?

public class AdditiveMap<K, V extends Number> extends HashMap<K, V> 
{ 
    @Override 
    public V put(final K key, final V value) 
    { 
     if (containsKey(key)) 
      // Second param Found 'Number', required 'V' 
      super.put(key, (Number)(get(key).intValue() + value.intValue())); 
     else 
      super.put(key, value); 
    } 
} 
+0

「Integer」は「V」と同じではないというメッセージが表示されていますが、もちろん正しいです。 –

+5

これは、 'merge'メソッドが' Map'インターフェースで設計されたものではありませんか? –

+0

@OliverCharlesworth 'V'は数字を伸ばします – Hatefiend

答えて

6

put方法でこれを行いMapを作成しないでください。 Map.put methodの契約は(強調鉱山)である:

このマップ(オプション)で指定されたキーに指定された値を関連付け。以前マップにキーのマッピングが含まれていた場合、は古い値が指定された値に置き換えられました。 (マップmは、m.containsKey(k)がtrueを返す場合にのみキーkのマッピングを含むと言われています)。

このようにマップはインタフェースの契約に違反します。

あなたは、もちろん、AdditiveMap.addValuesTogether(または何でも)メソッドを追加するのは自由です。あなた」;

map.merge(key, newValue, v -> v + newValue); 

本の主な利点は、この同じ構文がintlongfloatdoubleのために、すべての数値型(ほかの作品ということである。しかし、あなたは、単に既存のmerge方法を使用してオフ最善のだろう彼らはintに拡大されているので、あなたがそれらを追加するときshortcharbyteのためのキャストを必要とdは、あなたが)v -> v += newValueを使用して、明示的なキャストを避けることができ、実際には、Vを別のVに追加することができるMerger<V>戦略を提供せずに、一般的に行うことはできません。これは、この既存の方法を使用する場合に比べて非常に重いです。

+0

ありがとうございます。私はこのアプローチを使用します。それについてのオリジナルの方法がなぜ貧弱であるのか教えていただけますか?ありがとう。 – Hatefiend

関連する問題