我有一个类在列表中保存条目,可以通过某种方法不时清除和重新填充。 使用普通List作为类的最终成员是否被认为是更好的做法,还是每次重新填充时都应创建一个Immutablelist,从而丢失'final'修饰符?
我问的原因是因为其他对象可以从外部访问List,但是不能更改它们。我想向它们返回一个ImmutableList,但不是每次调用访问器时都复制它。
答案 0 :(得分:5)
我实际上并没有将Guava用于此用例,而只是JDK中的工具。
你应该做的是在你的班级中使用传统的,可变的列表实现 - 可能是一个ArrayList。但是,您的类应该将getList()方法实现为类似
的方法public List<Something> getList() {
return Collections.unmodifiableList(internalList);
}
这将确保其他对象无法修改列表,但可以根据需要修改列表。
答案 1 :(得分:2)
根据列表的修改频率/列表的大小,我可能会使用非最终的ImmutableList
字段。每次列表更改时,您的内部方法都会构造一个新的ImmutableList
。
如果列表经常被修改,或者它非常大(因此每次构建一个新列表的成本太高),我会使用带有Collections.unmodifiableList()
包装器的可变列表,如Louis建议的那样。 / p>
请注意,如果并发访问很重要(或使用易变的ImmutableList和某种锁定......),您可能还需要考虑CopyOnWriteArrayList。
答案 2 :(得分:1)
final
修饰符不保护List本身不被修改。它只是说引用永远不会指向另一个对象,但引用的对象可以改变。
不可变列表是不同的。不可变列表本身不能更改其内容,但只要它不是最终引用,您就可以将引用指向另一个列表。
因此,拥有最终的不可变列表是有意义的。当你不需要一个可变列表时,我总是使用不可变列表。
正如番石榴的一位主要开发者所说:“你不应该问你是否需要一个不可变的清单。你最好问一下你是否需要它是可变的。”不知道确切的词......他在youtube上的谷歌开发者频道中说过。