我想知道是否有List
实施允许快速contains
。我正在使用相当长的List
而我无法切换到Set
,因为我需要通过索引进行访问。我可以忽略现在可接受的性能,将来可能会或可能不会被接受。我可以创建一个HashSet
并对两者进行所有修改操作,但手动执行操作非常无聊且容易出错。
我知道让一个类像List
和Set
一样工作是不可能的(因为equals
语义不同),但我想知道是否有List
实现RandomAccess
并使用HashSet
加快contains
。
答案 0 :(得分:6)
我知道像
这样的课程是不可能的List
和Set
你试过LinkedHashSet
吗?从技术上讲,它是一个集合,但它保留了可能对您而言足够的顺序。但是,索引访问是线性的而不是内置的。
其他方法是将List
与自定义装饰器包装在一起,它们都委托给List
并维护内部Set
以加快contains
答案 1 :(得分:1)
BiMap<Integer, MyClass>
怎么样?这可以在Guava
BiMap<Integer, MyClass> map = HashBiMap.create();
//store by index
map.put(1, myObj1);
//get by index
MyClass retrievedObj = map.get(1);
//check if in map
if ( map.containsValue(retrievedObj) ) {
//...
}
我知道它没有实现List
接口。这里的主要限制是传统的List
意义上没有提供插入和删除;但你没有具体说明那些对你来说是否重要。
答案 2 :(得分:1)
你可以包装一个结合了两个世界的列表和hashSet
public class FastContainsList<T> extends AbstractSequentialList<T> implements RandomAccess{
//extending sequential because it bases itself of the ListIterator(int) and size() implementation
private List<T> list=new ArrayList<T>();
private Set<T> set=new HashSet<T>();
public int size(){
return list.size();
}
public boolean contains(Object o){//what it's about
return set.contains(o);
}
public ListIterator<T> listIterator(int i){
return new ConIterator(list.listIterator(i));
}
/*for iterator()*/
private ConIterator implements ListIterator<T>{
T obj;
ListIterator<T> it;
private ConIterator(ListIterator<T> it){
this.it = it
}
public T next(){
return obj=it.next();
}
public T previous(){
return obj=it.previous();
}
public void remove(){
it.remove();//remove from both
set.remove(obj);
}
public void set(T t){
it.set(t);
set.remove(obj);
set.add(obj=t);
}
public void add(T t){
it.add(t);
set.add(t);
}
//hasNext and hasPrevious + indexes still to be forwarded to it
}
}
答案 3 :(得分:1)
Apache Commons TreeList应该可以解决这个问题: http://commons.apache.org/proper/commons-collections/javadocs/api-release/org/apache/commons/collections4/list/TreeList.html
答案 4 :(得分:0)
您可以维护列表和设置。这将为您提供快速索引查找并包含(具有较小的开销)
BTW:如果您的列表很小,例如10个条目,使用普通列表可能没有任何区别。
答案 5 :(得分:0)
我认为包含HashMap
和List
的课程(正如您在帖子中所述)可能是快速contains
和access
的最佳选择。