JavaのUnmodifialeMapの使い道について
自分向け備忘録
下記のコードの問題点を考える。
class CustomerRecords { private Map<String, Customer> records; public Map<String, Customer> getCustomers() { return this.records; } }
getCustomers()
がreferenceを返してしまっているので、カプセル化に失敗していますね。
では、以下ではどうでしょうか。
class CustomerRecords implements Iterable<Customer> { private Map<String, Customer> records; public Map<String, Customer> getCustomers() { return this.records; } @Override public Iterator<Customer> iterator() { return records.values().iterator(); } }
マシですが、実はiteratorにはremove
メソッドがあるので、これも完璧なソリューションではないです。
なら、コピーしたオブジェクトを返せばいいのでは??
class CustomerRecords implements Iterable<Customer> { private Map<String, Customer> records; public Map<String, Customer> getCustomers() { return new Map<String, Customer>(this.records); } @Override public Iterator<Customer> iterator() { return records.values().iterator(); } }
これも完璧ではない。なぜなら、コピーしたオブジェクトが更に参照しているオブジェクトは、同じ参照を保持している可能性があるから。
ということで、UnmodifiableMapを使いましょう。
class CustomerRecords { private Map<String, Customer> records; public Map<String, Customer> getCustomers() { return Collections.unmodifiableMap(this.records); } }