Map<String,Object>
に変換するにはどうすればよい Map<String,String>
ですか?
これは動作しません:
Map<String,Object> map = new HashMap<String,Object>(); //Object is containing String
Map<String,String> newMap =new HashMap<String,String>(map);
Map<String,Object>
に変換するにはどうすればよい Map<String,String>
ですか?
これは動作しません:
Map<String,Object> map = new HashMap<String,Object>(); //Object is containing String
Map<String,String> newMap =new HashMap<String,String>(map);
Java 8/streams ができたので、リストにもう 1 つ可能な答えを追加できます。
各値が実際に オブジェクトであると仮定するとString
、へのキャストString
は安全なはずです。それ以外の場合は、オブジェクトを文字列にマッピングするための他のメカニズムを使用できます。
Map<String,Object> map = new HashMap<>();
Map<String,String> newMap = map.entrySet().stream()
.collect(Collectors.toMap(Map.Entry::getKey, e -> (String)e.getValue()));
Objects
のみが含まれている場合は、次のStrings
ように実行できます。
Map<String,Object> map = new HashMap<String,Object>(); //Object is containing String
Map<String,String> newMap =new HashMap<String,String>();
for (Map.Entry<String, Object> entry : map.entrySet()) {
if(entry.getValue() instanceof String){
newMap.put(entry.getKey(), (String) entry.getValue());
}
}
すべてObjects
がそうでない場合String
は、に置き換えることができ (String) entry.getValue()
ますentry.getValue().toString()
。
ジェネリック型は、コンパイル時の抽象化です。実行時には、すべてのマップが同じタイプになりMap<Object, Object>
ます。したがって、値が文字列であることが確実な場合は、Java コンパイラをごまかすことができます。
Map<String, Object> m1 = new HashMap<String, Object>();
Map<String, String> m2 = (Map) m1;
あるコレクションから別のコレクションにキーと値をコピーするのは冗長です。しかし、このアプローチは、ジェネリックスの型安全性に違反しているため、まだ良くありません。そのようなことを避けるために、コードを再検討する必要があるかもしれません。
以下は、既存のエントリを変換します。
TransformedMap.decorateTransform(params, keyTransformer, valueTransformer)
一方
MapUtils.transformedMap(java.util.Map map, keyTransformer, valueTransformer)
新しいエントリのみをマップに変換します
ブルートキャストと抑制された警告でこれを行うことができますが
Map<String,Object> map = new HashMap<String,Object>();
// Two casts in a row. Note no "new"!
@SuppressWarnings("unchecked")
Map<String,String> newMap = (HashMap<String,String>)(Map)map;
それは本当に要点が欠けています。:)
狭いジェネリック型をより広いジェネリック型に変換しようとすると、そもそも間違った型を使用していることになります。
類推として、大量のテキスト処理を行うプログラムがあると想像してください。処理の前半をObjects
(!!) を使用して実行し、後半を として正しい入力で実行することを決定したとString
想像しObject
てくださいString
。幸いなことに、Java でこれを行うことができます (この場合は簡単です)。ただし、前半で弱い型付けを使用しているという事実を隠しているだけです。悪い習慣、議論はありません。
ここでは違いはありません (キャストするのが難しいだけです)。常に強い型付けを使用する必要があります。少なくともいくつかの基本型を使用します。その後、ジェネリック ワイルドカードを使用して ("? extends BaseType" または "? super BaseType")、型の互換性と自動キャストを実現できます。さらに良いことに、正しい既知の型を使用してください。どの型でも実際に使用できる 100% 一般化されたコードがない限り、Object を使用しないでください。
それが役立つことを願っています! :) :)
注: 一般的な厳密な型指定と型キャストは、.java コードにのみ存在します。.class へのコンパイル後、ジェネリック型パラメーターのない生の型 (Map および HashMap) と、キーと値の自動型キャストが残ります。しかし、.java コード自体は厳密に型指定されており、簡潔であるため、非常に役立ちます。