マップインスタンスでメソッドUnsupportedOperationException
を呼び出したときに取得し続ける場合、マップの内容を空にするにはどうすればよい ですか?clear()
2 に答える
すべきではありません。連携するオブジェクトとそのメソッドのコントラクトに何か問題があります。変更可能なマップが必要ですが、変更できないビューが表示されます。コントラクトを再定義するか、それに応じて実装を採用する必要があります。そのマップを渡している人を制御できない場合は、変更できないビューを渡す理由がある可能性があります。
が(たとえば、から取得した)Map
の場合、新しい参照を作成してクリアすることを除いて、変更するためにできること(およびすべきこと)はほとんどありません。UnmodifiableMap
Collections.unmodifiableMap()
Map unmodifiable = Collections.unmodifiableMap(m);
Map newMap = new HashMap(unmodifiable);
newMap.clear();
unmodifiable = newMap;
とはいえ、実際にはを変更することは可能UnmodifiableMap
です。これは、インターフェイスを実装し、実際のをラップCollections.UnmodifiableMap
するクラスにすぎないことがわかりました。読み取り専用メソッドのラップを委任し、マップを変更するメソッドの実装にsをスローします。リフレクションでラップされる可能性があるため、変更することができます。Map
Map
Map
UnsupportedOperationException
Map
免責事項:これは細心の注意を払って使用する必要があることを考慮に入れてください。変更不可能なマップがライブラリなどによって提供されている場合、その性質について推測している可能性があり、その契約に違反すると、予期しない/望ましくない結果が生じる可能性があります。また、これは、予告なしに変更されたり、バージョン間で異なる可能性がある内部に依存している可能性があります。
// Creates a standard map
Map<String, String> myMap = new HashMap<String, String>();
myMap.put("1", "a");
myMap.put("2", "b");
// Creates an unmodifiableMap. Actually a wrapper for myMap.
Map unmodifiableMap = Collections.unmodifiableMap(myMap);
System.out.println("Size of unmodifiable map is: " + unmodifiableMap.size());
try{
// Get classes declared in java.util.Collections
Class[] classes = Collections.class.getDeclaredClasses();
for(Class cl : classes) {
// Look for the UnmodifiableMap class
if("java.util.Collections$UnmodifiableMap".equals(cl.getName())) {
// The wrapped Map is in an attribute called "m"
Field field = cl.getDeclaredField("m");
field.setAccessible(true);
// Get the wrapped map
Object obj = field.get(unmodifiableMap);
Map map = (Map) obj;
// modify it
map.clear();
}
}
}
catch (Exception e){ System.out.println(); }
System.out.println("Size of unmodifiable map is: " + unmodifiableMap.size());
(このブログ投稿のクレジット)