Map<String,String>
Javaでは、値を変更可能に保ちながら、変更不可能なキーを持つを作成するにはどうすればよいですか。
Map<String,String>
他の誰かが Map 値を追加/変更できるようにインターフェースを介してこれを渡したいのですが、Map キーを変更することはできません。
より高いレベルの問題の背景は、変数名のリスト/セット (ツリーのような構造を持つ) (Java 文字列として表される) を持っていることです。文字列) を各変数名に使用します。このインターフェースを複数実装して、ツリー階層の命名をさまざまな状況に合わせてさまざまな方法でエイリアスにできるようにしたいと考えています。インターフェイスの実装に、Map<String,String>
すでに設定されている一連のキー (値のデフォルトが含まれている可能性があります) を入力し、値 (キーではなく) を変更できるようにするのが最善の方法のようです。名前とエイリアスの間のマッピングを作成しているのでMap<>
、理にかなっています。
低レベルの問題に戻ります。コードを次のようにしたい:
public class MyClass
{
public interface IMyMapper
{
void build(Map<String,String> mapping);
}
IMyMapper mapper;
// How I'd like to use it
void work()
{
Map<String,String> map ;
// Magic something like Collections unmodifiableMap, but only for keys
// Maybe my question should be how this magic for UnmodifiableMap works, so I could reproduce it??
mapper.build(map);
// Because Maps<> are by reference, changed they made (to the values) would be reflected here
}
}
public class TheirClass implements MyClass.IMyMapper
{
@Override
public void build(Map<String,String> mapping)
{
// use mapping like Map<String,String> without extra/foreign classes
// but not be able to modify the Map keys
// only be able to change the Map values
// Should be able to use all of the awesome Map stuff, like foreach, values, compute
}
}
あることは知っていますがCollections unmodifiableMap(Map<> m)
、それによって値が変更できなくなります。私の値が変更可能なオブジェクトである場合、それらを変更することはできますが、私は固執したいと思いますStrings
(単一の String メンバーの set/get を使用して Class を作成したり、public String メンバーを使用して構造のようなクラスを作成したりすることは避けます)。
AKA、私は独自の変更可能なクラス値を作成することを避けCollections unmodifiableMap()
、キーをvalue references
変更不可能にするために使用したいと思います:
// mutable reference to a String
public class ExtraWorkForForEveryone
{
public String value;
public void setValue(String value) { ... }
public String getValue() { ... }
}
// and then use:
void work()
{
Map<String,ExtraWorkForEveryone> map;
map = Collections.unmodifiableMap( ... );
// because Collections.unmodifiableMap() only stops them from changing the Map references,
// the interfacer could still change the ExtraWorkForEveryone internals.
// so they could not change keys refs or value refs, but they could change value data.
mapper.build(map);
// Because Maps<> are by reference, changed they made (to the values) would be reflected here
}
独自の Map を拡張または実装してから、( how のようにCollections unmodifiableMap()
) キー throw を変更できるすべてのメソッドをオーバーライドできますUnsupportedOperationException
。しかし、Java 8 では、Lambda 関数を使用して追加された多数のメソッドがあり、キーを変更できない限り、インターフェイスの実装者がアクセスできると便利です。
別名、この長くてエラーが発生しやすい手法は避けたいと思います。
public final class FinalHashMap extends HashMap
{
@Override // anything that might be able to change the Map Keys
so_many_methods_and_edge_cases()
{ throws UnsupportedOperationException }
}
の値のデータの変更のみを許可する既存のインターフェイスはありますMaps<>
か?
変更不可能なキーMap<String,String>
を持ち、変更可能な値を持つaに似たものを作成するための他のオプションは何ですか? 可能であれば、適切なコーディング プラクティスに関心があります。