4

クラスに 2 つのマップがあります (ジェネリックは初めてです)

private Map<Integer, Integer> aMap = new ConcurrentHashMap<Integer, Integer>();
private Map<Integer, Short> bMap = new HashMap<Integer, Short>();

キーがマップに存在しない場合、ゼロ値を取得したい。したがって、入力を最小限に抑えるためにこのラッパーメソッドを作成しましたcontainsKey(key)

@SuppressWarnings("unchecked")
private <T extends Number> T getValue (Map<Integer, T> map, Integer key) {
    return (T) ((map.containsKey(key)) ? map.get(key) : 0);
}

私はそれを次のように呼びます

Integer a = getValue(aMap, 15); //okay in any case
Short b = getValue(bMap, 15); //15 key does not exist

2番目のケースでは、次のようになります。

ClassCastException: java.lang.Integer cannot be cast to java.lang.Short

したがって、おそらく のようなことをする必要があります: new Number(0)が、 Number は抽象的です。

どうすれば修正できますか?

編集:

私の考えは、追加のifなしで算術演算を行うことです:

Integer a = getValue(aMap, 15);
a = a + 10;
4

4 に答える 4

6

1 つの方法は、関数の引数としてデフォルト値を指定することです。

private <T extends Number> T getValue (Map<Integer, T> map, Integer key, T dflt) {
    return (T) ((map.containsKey(key)) ? map.get(key) : dflt);
}

public static void main(String[] args) {
    Integer a = getValue(aMap, 15, 0); //okay in any case
    Short b = getValue(bMap, 15, (short)0); //15 key does not exist
}
于 2013-03-04T10:34:16.360 に答える
3

Tそれについては、コードが参照できる方法を提供しなければ、多くのことを行うことはできません。

その時点での最も簡単なアプローチは、おそらく 0 値のマップを保持することです。

private static Map<Class<?>, Number> ZERO_VALUES = createZeroValues();

private static Map<Class<?>, Number> createZeroValues() {
    Map<Class<?>, Number> ret = new HashMap<Class<?>, Number>();
    ret.put(Integer.class, (int) 0);
    ret.put(Short.class, (short) 0);
    ret.put(Long.class, (long) 0);
    // etc
}

それで:

private <T extends Number> T getValue (Map<Integer, T> map, Integer key, Class<T> clazz) {
    return clazz.cast(map.containsKey(key) ? map.get(key) : ZERO_VALUES.get(clazz));
}

残念ながら、次のように呼び出す必要があります。

Short b = getValue(bMap, 15, Short.class);

基本的に、これはJavaジェネリックの制限です:(

于 2013-03-04T10:31:38.267 に答える
2

このような状況では、get()メソッドをオーバーライドするだけです。

 private Map<Integer, Short> bMap = new HashMap<Integer, Short>() {
     @Override
     public Short get(Object key) {
         return containsKey(key) ? super.get(key) : new Short(0);
     }
 };

そうすれば、どこでも使用でき、指定したとおりに動作します。

于 2013-03-04T11:13:06.650 に答える
0

デフォルトでは int になるため、0 を明示的に short にキャストします。そして、Short wrapper に変換します。Java では、プリミティブから別のタイプの Wrapper に直接変換することはできません。

于 2013-03-04T10:39:03.957 に答える