客观的
创建一个类以用作String对象的不可变列表。
方法
我决定利用Google Guava的ImmutableList<E>集合,而不是用Collections.unmodifiableList(List<? extends T> list)包装一个简单的List<E>因为我知道这可以避免对支持List<E进行不必要的并发检查>,它不知道被包装(来源:ImmutableCollectionsExplained)。
要求
- 具有跨线程使用的“价值持有者”的类
- 不应允许任何代码在创建后更改内部值
锦上添花
- 该类应实现Iterable<E>以按创建顺序对值进行迭代
- 给定的一组String应该只有一个类。
尝试
这里有一些尝试,虽然更多的组合是可能的。原谅幽默的演绎。
尝试#1(包括使用示例)
import java.util.List;
import com.google.common.collect.ImmutableList;
class BritnetSpearsSpellings implements Iterable<String> {
public static BritnetSpearsSpellings of(String... spellings) {
BritnetSpearsSpellings britneySpears = new BritnetSpearsSpellings();
britneySpears.spellings = ImmutableList.copyOf(spellings);
return britneySpears;
}
private List<String> spellings;
private BritnetSpearsSpellings() {
}
public List<String> getSpellings() {
return spellings;
}
}
@Override
public Iterator<String> iterator() {
return spellings.iterator();
}
public class Usage {
public static void main(String[] args) {
for (String sepllin : BritnetSpearsSpellings.of("Brittany Spears", "Brittney Spears", "Britany Spears"))
System.out.printf("You spel Britni like so: %s%n", sepllin);
}
}
}
尝试#2
class BritnetSpearsSpellings implements Iterable<String> {
public static BritnetSpearsSpellings of(String... spellings) {
BritnetSpearsSpellings britneySpears = new BritnetSpearsSpellings();
britneySpears.spellings = ImmutableList.copyOf(spellings);
return britneySpears;
}
private ImmutableList<String> spellings;
private BritnetSpearsSpellings() {
}
public ImmutableList<String> getSpellings() {
return spellings;
}
@Override
public Iterator<String> iterator() {
return spellings.iterator();
}
}
尝试#3
class BritnetSpearsSpellings implements Iterable<String> {
public static BritnetSpearsSpellings of(String... spellings) {
BritnetSpearsSpellings britneySpears = new BritnetSpearsSpellings(ImmutableList.copyOf(spellings));
return britneySpears;
}
private final ImmutableList<String> spellings;
private BritnetSpearsSpellings(ImmutableList<String> spellings) {
this.spellings = spellings;
}
public ImmutableList<String> getSpellings() {
return spellings;
}
@Override
public Iterator<String> iterator() {
return spellings.iterator();
}
}
差异总结
1 将List<E>保留在公共接口中,记录 JavaDoc 中的不变性。
2 将所有内容存储并公开为Google Guava的ImmutableList<E>
3 以创建专用构造函数为代价将内部引用保持为最终引用,这可能会使静态工厂方法初始化在没有其他初始化选项的情况下看起来很傻(实际上在真实类中存在)
问题
请帮助我在其中一种实现中进行选择,并说明您的选择背后的原因。
我认为方法 2 的主要缺点是客户需要了解/了解专门的Google Guava类型,而他们可能不应该这样做?