を返す:変更不可能なマップ
Map<String,Map<String,Object>>
が鍵を考えると、私は地図を返されます。
返されるマップを不変にするための推奨される方法は何ですか? (無編集/削除/追加)
基礎となるオブジェクトは、我々は、オブジェクトは不変にするnoオプションを持っていない
不変(無編集)されない
地図は不変である:
これは、本質的にことを意味します。
を返す:変更不可能なマップ
Map<String,Map<String,Object>>
が鍵を考えると、私は地図を返されます。
返されるマップを不変にするための推奨される方法は何ですか? (無編集/削除/追加)
基礎となるオブジェクトは、我々は、オブジェクトは不変にするnoオプションを持っていない
不変(無編集)されない
地図は不変である:
これは、本質的にことを意味します。
あなたがしなければならないことは、戻る地図の詳細なコピーを作成することです。
その後、全体マップが変更不可能にする、各マップは変更不可能にすることができます。
public Map<String,Map<String,Object>> makeUnModifiable(Map<String,Map<String,Object>> a){
for(Entry<String, Map<String, Object>> e:a.entrySet()){
e.setValue(Collections.unmodifiableMap(e.getValue()));
}
return Collections.unmodifiableMap(a);
}
本当の問題は、マップの値にアクセスできるようにすることです。それらのオブジェクトのコピーを作成することはできますが、それは問題を解決しません。オブジェクトクラスを不変にするか、setterメソッドを無効にするWrapperクラスを作成します。
それは、問題で必要に応じてオブジェクト自体を変更不可能にするものではありません。 – RealSkeptic
@RealSkepticそれは本当です。これは、オブジェクトクラスを知る必要がある非常に限られた数の方法でのみ行うことができます。 – f1sh
AbstractMap
を拡張することで、マップ値も変更不可能な変更不可能なマップを作成することができます。
変更不可能なマップを実装するには、プログラマは、このクラスを拡張して、マップのマッピングのセットビューを返します
entrySet
方法、の実装を提供する必要があります。通常、戻り値のセットはAbstractSet
の上に実装されます。このセットはadd
またはremove
メソッドをサポートしてはならず、イテレータはremove
メソッドをサポートしてはいけません。
package mcve;
import java.util.*;
public final class UnmodifiableMapOfMaps<K, L, V> extends AbstractMap<K, Map<L, V>> {
// Optionally Map<? extends K, ? extends Map<? extends L, ? extends V>>
// but it would make the code a lot more difficult to read.
private final Map<K, Map<L, V>> map;
public UnmodifiableMapOfMaps(Map<K, Map<L, V>> map) {
this.map = Objects.requireNonNull(map);
}
// Additionally override size(), get(), etc., entirely optionally.
// Doing so would merely be an optimization since AbstractMap
// implements those methods via the entrySet() iterator.
@Override
public Set<Entry<K, Map<L, V>>> entrySet() {
return new AbstractSet<Entry<K, Map<L, V>>>() {
@Override
public int size() {
return map.size();
}
@Override
public Iterator<Entry<K, Map<L, V>>> iterator() {
return new Iterator<Entry<K, Map<L, V>>>() {
private final Iterator<Entry<K, Map<L, V>>> it = map.entrySet().iterator();
@Override
public boolean hasNext() {
return it.hasNext();
}
@Override
public Entry<K, Map<L, V>> next() {
// Return the Entry as an immutable Entry with an
// unmodifiableMap as the value.
Entry<K, Map<L, V>> entry = it.next();
K key = entry.getKey();
Map<L, V> val = Collections.unmodifiableMap(entry.getValue());
return new SimpleImmutableEntry<>(key, val);
}
};
}
};
}
}
抽象コレクションは、彼らがゼロから新しいコンテナを記述することなく、かなり自明解けるこのような問題の多くを作るために精通していることには本当に偉大なクラスです。
不変オブジェクトを書き込む以外に、Javaで不変オブジェクトを作成する方法はありません。 Javaには、例えばC++のconst
。
interface ImmutableFoo {
int getValue();
}
interface MutableFoo extends ImmutableFoo {
void setValue(int value);
}
class Foo implements MutableFoo {
private int value;
public Foo(int value) { this.value = value; }
@Override public int getValue() { return value; }
@Override public void setValue(int value) { this.value = value; }
}
そうでない場合は、Foo
がある場合:実際に新しいオブジェクトをインスタンス化せずにこれを行うには
一つの方法は、次のようにImmutableFoo
あなたがセッターを公開したくない任意の時刻を返し、その後、インターフェースを書くことですあなたが変更できないクラスであれば、次のようなものを書く必要があります:
class FooAccessor {
private final Foo foo;
public FooAccessor(Foo foo) { this.foo = Objects.requireNonNull(foo); }
public int getValue() { return foo.getValue(); }
}
変更不可能なAbstractMap
の例と組み合わせて使用します。
[変更可能なマップを返す](https://stackoverflow.com/questions/7066618/returning-an-unmodifiable-map)の可能な複製 –
オブジェクトが不変であることを指定する方法はありません。オブジェクト。私はあなたの質問を理解しているので、マップを不変にすることを実際に求めているわけではありません。マップ内のオブジェクト*を不変にすることを求めています。あれは正しいですか?別の言い方をすると、基本的にはC++の 'const'のようなものが欲しいですが、それはJavaでは存在しません。オブジェクトをラップするプロキシを記述する必要があり、セッターや例外をスローしません。インターフェイスを使用すると便利です。 – Radiodef
実際には不変の 'Object' _for_が必要ですか?それを知らずに、有用な助言をするのは難しいです。 – Rook