CodeQuality / Guava:清除并填写最终列表或分配新的Immutablelist

时间:2011-11-17 13:56:26

标签: list immutability guava final

我有一个类在列表中保存条目,可以通过某种方法不时清除和重新填充。 使用普通List作为类的最终成员是否被认为是更好的做法,还是每次重新填充时都应创建一个Immutablelist,从而丢失'final'修饰符?

我问的原因是因为其他对象可以从外部访问List,但是不能更改它们。我想向它们返回一个ImmutableList,但不是每次调用访问器时都复制它。

3 个答案:

答案 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)

Java中的

final修饰符不保护List本身不被修改。它只是说引用永远不会指向另一个对象,但引用的对象可以改变。

不可变列表是不同的。不可变列表本身不能更改其内容,但只要它不是最终引用,您就可以将引用指向另一个列表。

因此,拥有最终的不可变列表是有意义的。当你不需要一个可变列表时,我总是使用不可变列表。

正如番石榴的一位主要开发者所说:“你不应该问你是否需要一个不可变的清单。你最好问一下你是否需要它是可变的。”不知道确切的词......他在youtube上的谷歌开发者频道中说过。