列表包含快速包含

时间:2011-11-11 20:48:59

标签: java list set

我想知道是否有List实施允许快速contains。我正在使用相当长的List而我无法切换到Set,因为我需要通过索引进行访问。我可以忽略现在可接受的性能,将来可能会或可能不会被接受。我可以创建一个HashSet并对两者进行所有修改操作,但手动执行操作非常无聊且容易出错。

我知道让一个类像ListSet一样工作是不可能的(因为equals语义不同),但我想知道是否有List实现RandomAccess并使用HashSet加快contains

6 个答案:

答案 0 :(得分:6)

  

我知道像ListSet

这样的课程是不可能的

你试过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)

答案 4 :(得分:0)

您可以维护列表和设置。这将为您提供快速索引查找并包含(具有较小的开销)

BTW:如果您的列表很小,例如10个条目,使用普通列表可能没有任何区别。

答案 5 :(得分:0)

我认为包含HashMapList的课程(正如您在帖子中所述)可能是快速containsaccess的最佳选择。