如果我的数据结构如下:
ImmutableObj<MutableMap<String,Integer>> myObj;
以上是否足以确保免疫力?或者我是否必须使MutableMap
不可变?
答案 0 :(得分:1)
当你不公开像这样的原始可变对象的链接时是安全的(带有列表的例子,地图的相同方法出现在Collections类中):
List<String> strings = Arrays.asList("Foo", "Bar");
List<String> immutableStrings = Collections.unmodifiableList(strings);
因为您可能必须通过字符串列表修改immutableStrings列表。 更好的方法是根本没有可变列表的链接:
List<String> immutableStrings = Collections.unmodifiableList(Arrays.asList("Foo", "Bar"));
这里我们没有使用foo和bar链接到内部可变列表,也无法修改immutableStrings列表。
这是合成的例子,根据你提问的对话,我明白你可能想要这样的东西:
public Map<String, Integer> wordFruquencyIn(String book, String word) {
//do calculation here
Map<String, Integer> result = //result
return Collections.unmodifiableMap(result); // return unmodifiable map
}
最好创建代表计算结果而不是地图的自定义类,因为Map,List等的合同......不清楚你不知道它们是否可变(缺少方法isMutable()和缺乏一般早期Java版本中的设计(参见本例中的LSP原理))。重构后你的代码可能是这样的:
public Statistics wordFruquencyIn(String book, String word) {
//do calculation here
Map<String, Integer> result = //result
return new StatisticsImpl(result);
}
public interface Statistics {
public String word() {}
public int times() {}
}
您可以创建任何实现Statistics接口的实现,该接口实现此接口的合约并且具有内部映射或任何可变数据,只有一种与此类通信的方式是询问返回已经不可变字符串的word()
或{{ 1}}返回一个原语。