]> source.dussan.org Git - vaadin-framework.git/commitdiff
ListSet implementation for #4106 - BeanItemContainer slow in some instances
authorArtur Signell <artur.signell@itmill.com>
Tue, 2 Mar 2010 13:57:28 +0000 (13:57 +0000)
committerArtur Signell <artur.signell@itmill.com>
Tue, 2 Mar 2010 13:57:28 +0000 (13:57 +0000)
svn changeset:11593/svn branch:6.3

src/com/vaadin/data/util/ListSet.java [new file with mode: 0644]

diff --git a/src/com/vaadin/data/util/ListSet.java b/src/com/vaadin/data/util/ListSet.java
new file mode 100644 (file)
index 0000000..8dc8c6b
--- /dev/null
@@ -0,0 +1,198 @@
+package com.vaadin.data.util;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Collection;\r
+import java.util.HashSet;\r
+import java.util.Iterator;\r
+\r
+/**\r
+ * ListSet is an internal Vaadin class which implements a combination of a List\r
+ * and a Set. The main purpose of this class is to provide a fast\r
+ * {@link #contains(Object)} method. Each inserted object must by unique (as\r
+ * specified by {@link #equals(Object)}).\r
+ * \r
+ * This class is subject to change and should not be used outside Vaadin core.\r
+ */\r
+public class ListSet<E> extends ArrayList<E> {\r
+    private HashSet<E> itemSet = null;\r
+\r
+    public ListSet() {\r
+        super();\r
+        itemSet = new HashSet<E>();\r
+    }\r
+\r
+    public ListSet(Collection<? extends E> c) {\r
+        super(c);\r
+        itemSet = new HashSet<E>(c.size());\r
+        itemSet.addAll(c);\r
+    }\r
+\r
+    public ListSet(int initialCapacity) {\r
+        super(initialCapacity);\r
+        itemSet = new HashSet<E>(initialCapacity);\r
+    }\r
+\r
+    // Delegate contains operations to the set\r
+    @Override\r
+    public boolean contains(Object o) {\r
+        return itemSet.contains(o);\r
+    }\r
+\r
+    @Override\r
+    public boolean containsAll(Collection<?> c) {\r
+        return itemSet.containsAll(c);\r
+    }\r
+\r
+    // Methods for updating the set when the list is updated.\r
+    @Override\r
+    public boolean add(E e) {\r
+        if (contains(e)) {\r
+            // Duplicates are not allowed\r
+            return false;\r
+        }\r
+\r
+        if (super.add(e)) {\r
+            itemSet.add(e);\r
+            return true;\r
+        } else {\r
+            return false;\r
+        }\r
+    };\r
+\r
+    /**\r
+     * Works as java.util.ArrayList#add(int, java.lang.Object) but returns\r
+     * immediately if the element is already in the ListSet.\r
+     */\r
+    @Override\r
+    public void add(int index, E element) {\r
+        if (contains(element)) {\r
+            // Duplicates are not allowed\r
+            return;\r
+        }\r
+\r
+        super.add(index, element);\r
+        itemSet.add(element);\r
+    }\r
+\r
+    @Override\r
+    public boolean addAll(Collection<? extends E> c) {\r
+        boolean modified = false;\r
+        Iterator<? extends E> i = c.iterator();\r
+        while (i.hasNext()) {\r
+            E e = i.next();\r
+            if (contains(e)) {\r
+                continue;\r
+            }\r
+\r
+            if (add(e)) {\r
+                itemSet.add(e);\r
+                modified = true;\r
+            }\r
+        }\r
+        return modified;\r
+    }\r
+\r
+    @Override\r
+    public boolean addAll(int index, Collection<? extends E> c) {\r
+        ensureCapacity(size() + c.size());\r
+\r
+        boolean modified = false;\r
+        Iterator<? extends E> i = c.iterator();\r
+        while (i.hasNext()) {\r
+            E e = i.next();\r
+            if (contains(e)) {\r
+                continue;\r
+            }\r
+\r
+            add(index++, e);\r
+            itemSet.add(e);\r
+            modified = true;\r
+        }\r
+\r
+        return modified;\r
+    }\r
+\r
+    @Override\r
+    public void clear() {\r
+        super.clear();\r
+        itemSet.clear();\r
+    }\r
+\r
+    @Override\r
+    public int indexOf(Object o) {\r
+        if (!contains(o)) {\r
+            return -1;\r
+        }\r
+\r
+        return super.indexOf(o);\r
+    }\r
+\r
+    @Override\r
+    public int lastIndexOf(Object o) {\r
+        if (!contains(o)) {\r
+            return -1;\r
+        }\r
+\r
+        return super.lastIndexOf(o);\r
+    }\r
+\r
+    @Override\r
+    public E remove(int index) {\r
+        E e = super.remove(index);\r
+\r
+        if (e != null) {\r
+            itemSet.remove(e);\r
+        }\r
+\r
+        return e;\r
+    }\r
+\r
+    @Override\r
+    public boolean remove(Object o) {\r
+        if (super.remove(o)) {\r
+            itemSet.remove(o);\r
+            return true;\r
+        } else {\r
+            return false;\r
+        }\r
+    }\r
+\r
+    @Override\r
+    protected void removeRange(int fromIndex, int toIndex) {\r
+        HashSet<E> toRemove = new HashSet<E>();\r
+        for (int idx = fromIndex; idx < toIndex; idx++) {\r
+            toRemove.add(get(idx));\r
+        }\r
+        super.removeRange(fromIndex, toIndex);\r
+        itemSet.removeAll(toRemove);\r
+    }\r
+\r
+    @Override\r
+    public E set(int index, E element) {\r
+        if (contains(element)) {\r
+            // Element already exist in the list\r
+            if (get(index) == element) {\r
+                // At the same position, nothing to be done\r
+                return element;\r
+            } else {\r
+                // At another position, cannot set\r
+                return null;\r
+            }\r
+        }\r
+\r
+        E old = super.set(index, element);\r
+        itemSet.remove(old);\r
+        itemSet.add(element);\r
+\r
+        return old;\r
+    }\r
+\r
+    @SuppressWarnings("unchecked")\r
+    @Override\r
+    public Object clone() {\r
+        ListSet<E> v = (ListSet<E>) super.clone();\r
+        v.itemSet = new HashSet<E>(itemSet);\r
+        return v;\r
+    }\r
+\r
+}\r