我有一个我想要实现的接口,它包含以下方法签名:
/**
* Return an umodifiable ordered collection
*/
public List<String> getItems();
在我的特定实现中,我需要项目是唯一的。实现这个的最佳方法是什么?
我考虑过了
private List<String> items = new ArrayList<String>();
public List<String> getItems(){
return Collections.unmodifiableList(items);
}
public void addItem(String s){
// Inefficient -- has to scan entire list for contains
if (!items.contains(s)) items.add(s);
}
和
private LinkedHashSet<String> items = new LinkedHashSet<String>();
public List<String> getItems(){
// Inefficient -- has to copy the list
return Collections.unmodifiableList(new ArrayList(items));
}
public void addItem(String s){
items.add(s);
}
我真的很喜欢LinkedHashSet来实现List接口,所以我可以直接从第二种方法返回它。是否有解决方案或更好的解决方案?
答案 0 :(得分:3)
结合你的方法:
private Set<String> itemSet = new HashSet<String>();
private List<String> itemList = new ArrayList<String>();
public List<String> getItems() {
return Collections.unmodifiableList(itemList);
}
public addItem(String s) {
if (itemSet.add(s)) {
itemList.add(s);
}
}
答案 1 :(得分:2)
根据您的不可修改性限制,使用Guava库可能会很简单。 Guava的ImmutableSet
班级有一个asList()
视图,可让您将ImmutableSet
视为ImmutableList
。 asList()
需要O(1)时间,返回的List
支持恒定时间随机访问。
答案 2 :(得分:1)
由于引导我走这条道路的人删除了他们的答案,我将自己作为答案提交。 (对不起,既然你的答案被删除了,我不知道你是谁。)
界面可以更改为
/**
* Return an umodifiable ordered collection
*/
Collection<String> getItems();
然后实现可以使用LinkedHashSet没有问题:
private LinkedHashSet<String> items = new LinkedHashSet<String>();
public Collection<String> getItems(){
return Collections.unmodifiableSet(items);
}
public void addItem(String s){
items.add(s);
}
这将要求接口在某个可以更改的位置(而不是第三方),可以类似地跟踪和更改实现它的所有类,并且调用它的地方不会使用像{{ 1}}。