1

我有一个要实现的接口,其中包含以下方法签名:

/** 
 * 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 接口,这样我就可以直接从我的第二种方法中返回它。是否有解决方法或更好的解决方案?

4

3 回答 3

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);
    }
}
于 2013-05-29T14:29:28.847 回答
2

根据您的不可修改性约束,使用Guava库可能很简单。Guava 的ImmutableSet类有一个asList()视图,可以让您ImmutableSetImmutableList. asList()花费 O(1) 时间并且返回List支持恒定时间随机访问。

于 2013-05-29T16:23:05.957 回答
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);
}

这将要求接口在某个可以更改的地方(不是第三方),所有实现它的类都可以类似地被跟踪和更改,并且调用它的地方不使用 List 等特性get(int i)

于 2013-05-29T14:46:34.943 回答