web-dev-qa-db-ja.com

ハッシュマップへの安全なキャスト

マップをハッシュマップに安全にキャストするにはどうすればよいですか?

クラスキャスト例外を回避したい

HashMap<String, String> hMap;

public void setHashMap(Map map){
    hMap = (HashMap<String, String>) map;
}
11
Stainedart

(浅い)コピーを作成する場合:

HashMap<String, String> copy = new HashMap<String, String>(map);

まだHashMapでない場合にのみこれを実行したい場合:

HashMap<String, String> hashMap = 
   (map instanceof HashMap) 
      ? (HashMap) map 
      : new HashMap<String, String>(map);
31
Thilo

ClassCastExceptionNullPointerExceptionなどの例外を回避するには、関数を次のようにする必要があります。ここでは、あらゆる種類のMapオブジェクトがHashMapにクラスのフィールドに割り当てられます。

public void setHashMap(Map<String, String> map) {

    if (map != null && map instanceof HashMap<?, ?>) {
        hMap = (HashMap<String, String>) map;
    } else if (map != null) {
        hMap.putAll(map);
    }
}
3
Bhavik Ambani

一般に、クラスキャスト例外のリスクなしに、MapHashMapにタイプキャストすることはできません。 MapTreeMapの場合、キャストは失敗します(失敗する必要があります)。

キャストする前にinstanceofを使用して型をチェックすることで、例外を回避できますが、テストで「HashMapではない」と表示された場合はスタックします。キャストを機能させることはできません。

実用的な解決策は次のとおりです。

  • hMapMapではなくHashMapとして宣言します。
  • Mapエントリを新しく作成されたHashMapにコピーするか、または
  • (うん)実際のマップをラップするカスタムHashMapサブクラスを作成します。

(これらのアプローチのいずれもすべての場合に機能するわけではありません...しかし、マップが何に使用されるかについての詳細がなければ、特定の推奨を行うことはできません。)


そして、あなたがそれにいる間、問題のあるライブラリのプロバイダーにバグレポートを提出することが適切かもしれません。特定のMap実装を使用するように強制することは、(表面的には)悪い考えです。

3
Stephen C

できるよ:

if (map instanceof HashMap) {
   hMap = (HashMap<String, String>) map;
} else {
  //do whatever you want instead of throwing an exception
}

または、キャストをtry/catchで囲み、例外が発生したときにそれをキャプチャします。

0
palako

HashMapにキャストしないでください!マップにキャスト!
本当に質問の理由がある場合は、MapがMapのインスタンスではない場合に備えて、新しいHashMapを作成する必要があります。
しかし、これは悪い考えです。

0
AlexWien

常にHashMap<String, String>であると想定する場合は、これを実行しないのはなぜですか。

HashMap<String, String> hMap;

public void setHashMap(HashMap<String, String> map){
    hMap = map;
}

Mapを受け入れるより一般的なものが必要な場合:

public void setHashMap(Map<String, String> map){
    if (map != null)
        hMap = new HashMap<String, String>(map);
    else
        hMap = new HashMap<String, String>();
}

鋳造は必要ありません。また、あなたの例には戻り値の型がありませんでした。 voidを入れるつもりだったと思います。

0
Brian