]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.utils.datastructures/src/org/simantics/utils/datastructures/MapList.java
Switch MapList to use Java HashMap
[simantics/platform.git] / bundles / org.simantics.utils.datastructures / src / org / simantics / utils / datastructures / MapList.java
index aeef0fd1fff48eae3cb759b9719fe50b851eb012..cdfa9f7829ddbfb4065d95f9c4ef27cf774e306d 100644 (file)
-/*******************************************************************************\r
- * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
- * in Industry THTH ry.\r
- * All rights reserved. This program and the accompanying materials\r
- * are made available under the terms of the Eclipse Public License v1.0\r
- * which accompanies this distribution, and is available at\r
- * http://www.eclipse.org/legal/epl-v10.html\r
- *\r
- * Contributors:\r
- *     VTT Technical Research Centre of Finland - initial API and implementation\r
- *******************************************************************************/\r
-/*\r
- * 16.8.2006\r
- */\r
-package org.simantics.utils.datastructures;\r
-\r
-import gnu.trove.map.hash.THashMap;\r
-\r
-import java.util.ArrayList;\r
-import java.util.Collection;\r
-import java.util.Collections;\r
-import java.util.List;\r
-import java.util.Map;\r
-import java.util.Map.Entry;\r
-import java.util.Set;\r
-\r
-/**\r
- * MapList is a data structure with map on left side and arraylist on right side.\r
- * <p>\r
- * \r
- * @author Toni Kalajainen\r
- */\r
-public class MapList<L, R> {\r
-\r
-    @SuppressWarnings("rawtypes")\r
-    public static final MapList EMPTY_MAPLIST = new MapList() {\r
-        private static final String IMMUTABLE_MSG = "Cannot modify immutable empty MapList";\r
-\r
-        @Override\r
-        public void add(Object key) {\r
-            throw new UnsupportedOperationException(IMMUTABLE_MSG);\r
-        }\r
-        @Override\r
-        public void add(Object key, int index, Object value) {\r
-            throw new UnsupportedOperationException(IMMUTABLE_MSG);\r
-        }\r
-        @Override\r
-        public void add(Object key, Object value) {\r
-            throw new UnsupportedOperationException(IMMUTABLE_MSG);\r
-        }\r
-        @Override\r
-        public void addAll(Object key, Collection values) {\r
-            throw new UnsupportedOperationException(IMMUTABLE_MSG);\r
-        }\r
-        @Override\r
-        public void clear() {\r
-            throw new UnsupportedOperationException(IMMUTABLE_MSG);\r
-        }\r
-        @Override\r
-        public boolean remove(Object key) {\r
-            throw new UnsupportedOperationException(IMMUTABLE_MSG);\r
-        }\r
-        public boolean remove(Object key, Object value) {\r
-            throw new UnsupportedOperationException(IMMUTABLE_MSG);\r
-        }\r
-    };\r
-\r
-    @SuppressWarnings("unchecked")\r
-    public static <L, R> MapList<L, R> emptyMapList() {\r
-        return EMPTY_MAPLIST;\r
-    }\r
-\r
-    protected Map<L, List<R>> lists;\r
-\r
-    public MapList() {\r
-       lists = new THashMap<L, List<R>>();\r
-    }\r
-    \r
-    @SuppressWarnings("unchecked")\r
-       public MapList( Class<?> mapClass ) {\r
-       try {\r
-                       lists = (Map<L, List<R>>) mapClass.newInstance();\r
-               } catch (InstantiationException e) {\r
-                       throw new RuntimeException( e );\r
-               } catch (IllegalAccessException e) {\r
-                       throw new RuntimeException( e );\r
-               }\r
-    }\r
-\r
-    public MapList(MapList<L, R> copyFrom) {\r
-        for (Entry<L, List<R>> e : copyFrom.lists.entrySet())\r
-            lists.put( e.getKey(), new ArrayList<R>(e.getValue()) );\r
-    }\r
-\r
-       public static <L, R> MapList<L, R> use( Map<L, List<R>> map ) {\r
-               MapList<L, R> result = new MapList<L, R>();\r
-               result.lists = map;\r
-               return result;\r
-       }\r
-    \r
-    public void add(L key) {\r
-        getOrCreateList(key);\r
-    }\r
-\r
-    public void add(L key, R value)\r
-    {\r
-        List<R> list = getOrCreateList(key);\r
-        list.add(value);\r
-    }\r
-\r
-    public void add(L key, int index, R value)\r
-    {\r
-        ArrayList<R> list = getOrCreateList(key);\r
-        list.add(index, value);\r
-    }\r
-\r
-       public void addAll(L key, Collection<R> values) {\r
-               ArrayList<R> list = getOrCreateList(key);\r
-               list.addAll(values);\r
-       }\r
-    \r
-    private ArrayList<R> getOrCreateList(L key)\r
-    {\r
-        ArrayList<R> list = (ArrayList<R>) lists.get(key);\r
-        if (list==null) {\r
-            list = new ArrayList<R>(1);\r
-            lists.put(key, list);\r
-        }\r
-        return list;\r
-    }\r
-\r
-    private List<R> getList(L key)\r
-    {\r
-        return lists.get(key);\r
-    }\r
-\r
-    public boolean remove(L key, R value)\r
-    {\r
-        List<R> list = getList(key);\r
-        if (list==null) return false;\r
-        boolean result = list.remove(value);\r
-        if (list.size()==0)\r
-            lists.remove(key);\r
-        return result;\r
-    }\r
-\r
-    public boolean remove(L key)\r
-    {\r
-        List<R> list = getList(key);\r
-        if (list==null) return false;\r
-        lists.remove(key);\r
-        return true;\r
-    }\r
-\r
-    public void clear()\r
-    {\r
-        lists.clear();\r
-    }\r
-\r
-    public L[] getKeys(L[] list)\r
-    {\r
-        return lists.keySet().toArray(list);\r
-    }\r
-\r
-    public Set<L> getKeys()\r
-    {\r
-        return lists.keySet();\r
-    }\r
-\r
-    public int getKeySize() {\r
-        return lists.size();\r
-    }\r
-\r
-    public boolean containsKey(L key)\r
-    {\r
-        return lists.containsKey(key);\r
-    }\r
-\r
-    public boolean contains(L key, R obj)\r
-    {\r
-        List<R> l = lists.get(key);\r
-        if (l==null) return false;\r
-        return l.contains(obj);\r
-\r
-    }\r
-\r
-    public R[] getValues(L key, R[] list)\r
-    {\r
-        List<R> l = lists.get(key);\r
-        if (l==null) return null;\r
-        return l.toArray(list);\r
-    }\r
-\r
-    /**\r
-     * @param key\r
-     *            the key to get values for\r
-     * @param list\r
-     *            the list to fill with existing values for specified key. Fills\r
-     *            this array with at maximum as many values as there is room for\r
-     *            in the array even if there are more values available in the\r
-     *            maplist for the specified key.\r
-     * @return the amount of values existing for the key. May be smaller or\r
-     *         larger than the size of the provided list. If smaller, only the\r
-     *         first array indexes will be filled with data and if larger, all\r
-     *         array indexes will be filled with data.\r
-     */\r
-    public int getAtMostValues(L key, R[] list)\r
-    {\r
-        List<R> l = lists.get(key);\r
-        if (l==null) return 0;\r
-        int valueCount = l.size();\r
-        int size = Math.min(valueCount, list.length);\r
-        for (int i = 0; i < size; ++i)\r
-            list[i] = l.get(i);\r
-        return valueCount;\r
-    }\r
-\r
-    /**\r
-     * Returns a the internal list values for the specified key. The list is\r
-     * valid as long as it contains elements. The list should not be modified\r
-     * but the return value of this method does not enforce it like\r
-     * {@link #getValues(Object)} does. Use this method when you know you will\r
-     * not risk a 3rd party modifying the returned list and you want to avoid\r
-     * the cost of extra memory allocation through\r
-     * {@link Collections#unmodifiableList(List)}.\r
-     * \r
-     * @param key\r
-     *            the key to look values for\r
-     * @return empty unmodifiable list if there is no list with the specified\r
-     *         key, otherwise an unmodifiable version of the stored list\r
-     */\r
-    public List<R> getValuesUnsafe(L key)\r
-    {\r
-        List<R> l = lists.get(key);\r
-        return l != null ? l : Collections.<R>emptyList();\r
-    }\r
-\r
-    /**\r
-     * Returns a read-only reference to the values. The list is valid as long as\r
-     * it contains elements.\r
-     * \r
-     * @param key\r
-     * @return empty unmodifiable list if there is no list with the specified key,\r
-     *         otherwise an unmodifiable version of the stored list\r
-     */\r
-    public List<R> getValues(L key)\r
-    {\r
-        List<R> l = lists.get(key);\r
-        if (l==null) return Collections.emptyList();\r
-        return Collections.unmodifiableList(l);\r
-    }\r
-\r
-    /**\r
-     * Returns a copy of the values\r
-     * \r
-     * @param key\r
-     * @return empty unmodifiable list if there is no list with the specified key,\r
-     *         otherwise a copy of the stored list\r
-     */\r
-    public List<R> getValuesSnapshot(L key)\r
-    {\r
-        List<R> l = lists.get(key);\r
-        if (l==null) return Collections.emptyList();\r
-        return new ArrayList<R>(l);\r
-    }\r
-    \r
-    public List<R> getAllValuesSnapshot() \r
-    {\r
-        return getAllValuesSnapshot(null);\r
-    }\r
-\r
-    public List<R> getAllValuesSnapshot(List<R> result) \r
-    {\r
-        if (result == null)\r
-            result = new ArrayList<R>();\r
-        for (List<R> right : lists.values()) {\r
-            result.addAll(right);\r
-        }\r
-        return result;\r
-    }\r
-\r
-    public boolean isEmpty() {\r
-        return lists.isEmpty();\r
-    }\r
-\r
-    /**\r
-     * Makes _this_ maplist immutable.\r
-     */\r
-    public void makeImmutable() {\r
-        for (Entry<L, List<R>> e : lists.entrySet())\r
-            lists.put(e.getKey(), Collections.unmodifiableList(e.getValue()));\r
-        lists = Collections.unmodifiableMap(lists);\r
-    }\r
-\r
-}\r
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management
+ * in Industry THTH ry.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     VTT Technical Research Centre of Finland - initial API and implementation
+ *******************************************************************************/
+/*
+ * 16.8.2006
+ */
+package org.simantics.utils.datastructures;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+
+/**
+ * MapList is a data structure with map on left side and arraylist on right side.
+ * <p>
+ * 
+ * @author Toni Kalajainen
+ */
+public class MapList<L, R> {
+
+    @SuppressWarnings("rawtypes")
+    public static final MapList EMPTY_MAPLIST = new MapList() {
+        private static final String IMMUTABLE_MSG = "Cannot modify immutable empty MapList";
+
+        @Override
+        public void add(Object key) {
+            throw new UnsupportedOperationException(IMMUTABLE_MSG);
+        }
+        @Override
+        public void add(Object key, int index, Object value) {
+            throw new UnsupportedOperationException(IMMUTABLE_MSG);
+        }
+        @Override
+        public void add(Object key, Object value) {
+            throw new UnsupportedOperationException(IMMUTABLE_MSG);
+        }
+        @Override
+        public void addAll(Object key, Collection values) {
+            throw new UnsupportedOperationException(IMMUTABLE_MSG);
+        }
+        @Override
+        public void clear() {
+            throw new UnsupportedOperationException(IMMUTABLE_MSG);
+        }
+        @Override
+        public boolean remove(Object key) {
+            throw new UnsupportedOperationException(IMMUTABLE_MSG);
+        }
+        public boolean remove(Object key, Object value) {
+            throw new UnsupportedOperationException(IMMUTABLE_MSG);
+        }
+    };
+
+    @SuppressWarnings("unchecked")
+    public static <L, R> MapList<L, R> emptyMapList() {
+        return EMPTY_MAPLIST;
+    }
+
+    protected Map<L, List<R>> lists;
+
+    public MapList() {
+       lists = new HashMap<L, List<R>>();
+    }
+    
+    @SuppressWarnings("unchecked")
+       public MapList( Class<?> mapClass ) {
+       try {
+                       lists = (Map<L, List<R>>) mapClass.newInstance();
+               } catch (InstantiationException e) {
+                       throw new RuntimeException( e );
+               } catch (IllegalAccessException e) {
+                       throw new RuntimeException( e );
+               }
+    }
+
+    public MapList(MapList<L, R> copyFrom) {
+        for (Entry<L, List<R>> e : copyFrom.lists.entrySet())
+            lists.put( e.getKey(), new ArrayList<R>(e.getValue()) );
+    }
+
+       public static <L, R> MapList<L, R> use( Map<L, List<R>> map ) {
+               MapList<L, R> result = new MapList<L, R>();
+               result.lists = map;
+               return result;
+       }
+    
+    public void add(L key) {
+        getOrCreateList(key);
+    }
+
+    public void add(L key, R value)
+    {
+        List<R> list = getOrCreateList(key);
+        list.add(value);
+    }
+
+    public void add(L key, int index, R value)
+    {
+        ArrayList<R> list = getOrCreateList(key);
+        list.add(index, value);
+    }
+
+       public void addAll(L key, Collection<R> values) {
+               ArrayList<R> list = getOrCreateList(key);
+               list.addAll(values);
+       }
+    
+    private ArrayList<R> getOrCreateList(L key)
+    {
+        ArrayList<R> list = (ArrayList<R>) lists.get(key);
+        if (list==null) {
+            list = new ArrayList<R>(1);
+            lists.put(key, list);
+        }
+        return list;
+    }
+
+    private List<R> getList(L key)
+    {
+        return lists.get(key);
+    }
+
+    public boolean remove(L key, R value)
+    {
+        List<R> list = getList(key);
+        if (list==null) return false;
+        boolean result = list.remove(value);
+        if (list.size()==0)
+            lists.remove(key);
+        return result;
+    }
+
+    public boolean remove(L key)
+    {
+        List<R> list = getList(key);
+        if (list==null) return false;
+        lists.remove(key);
+        return true;
+    }
+
+    public void clear()
+    {
+        lists.clear();
+    }
+
+    public L[] getKeys(L[] list)
+    {
+        return lists.keySet().toArray(list);
+    }
+
+    public Set<L> getKeys()
+    {
+        return lists.keySet();
+    }
+
+    public int getKeySize() {
+        return lists.size();
+    }
+
+    public boolean containsKey(L key)
+    {
+        return lists.containsKey(key);
+    }
+
+    public boolean contains(L key, R obj)
+    {
+        List<R> l = lists.get(key);
+        if (l==null) return false;
+        return l.contains(obj);
+
+    }
+
+    public R[] getValues(L key, R[] list)
+    {
+        List<R> l = lists.get(key);
+        if (l==null) return null;
+        return l.toArray(list);
+    }
+
+    /**
+     * @param key
+     *            the key to get values for
+     * @param list
+     *            the list to fill with existing values for specified key. Fills
+     *            this array with at maximum as many values as there is room for
+     *            in the array even if there are more values available in the
+     *            maplist for the specified key.
+     * @return the amount of values existing for the key. May be smaller or
+     *         larger than the size of the provided list. If smaller, only the
+     *         first array indexes will be filled with data and if larger, all
+     *         array indexes will be filled with data.
+     */
+    public int getAtMostValues(L key, R[] list)
+    {
+        List<R> l = lists.get(key);
+        if (l==null) return 0;
+        int valueCount = l.size();
+        int size = Math.min(valueCount, list.length);
+        for (int i = 0; i < size; ++i)
+            list[i] = l.get(i);
+        return valueCount;
+    }
+
+    /**
+     * Returns a the internal list values for the specified key. The list is
+     * valid as long as it contains elements. The list should not be modified
+     * but the return value of this method does not enforce it like
+     * {@link #getValues(Object)} does. Use this method when you know you will
+     * not risk a 3rd party modifying the returned list and you want to avoid
+     * the cost of extra memory allocation through
+     * {@link Collections#unmodifiableList(List)}.
+     * 
+     * @param key
+     *            the key to look values for
+     * @return empty unmodifiable list if there is no list with the specified
+     *         key, otherwise an unmodifiable version of the stored list
+     */
+    public List<R> getValuesUnsafe(L key)
+    {
+        List<R> l = lists.get(key);
+        return l != null ? l : Collections.<R>emptyList();
+    }
+
+    /**
+     * Returns a read-only reference to the values. The list is valid as long as
+     * it contains elements.
+     * 
+     * @param key
+     * @return empty unmodifiable list if there is no list with the specified key,
+     *         otherwise an unmodifiable version of the stored list
+     */
+    public List<R> getValues(L key)
+    {
+        List<R> l = lists.get(key);
+        if (l==null) return Collections.emptyList();
+        return Collections.unmodifiableList(l);
+    }
+
+    /**
+     * Returns a copy of the values
+     * 
+     * @param key
+     * @return empty unmodifiable list if there is no list with the specified key,
+     *         otherwise a copy of the stored list
+     */
+    public List<R> getValuesSnapshot(L key)
+    {
+        List<R> l = lists.get(key);
+        if (l==null) return Collections.emptyList();
+        return new ArrayList<R>(l);
+    }
+    
+    public List<R> getAllValuesSnapshot() 
+    {
+        return getAllValuesSnapshot(null);
+    }
+
+    public List<R> getAllValuesSnapshot(List<R> result) 
+    {
+        if (result == null)
+            result = new ArrayList<R>();
+        for (List<R> right : lists.values()) {
+            result.addAll(right);
+        }
+        return result;
+    }
+
+    public boolean isEmpty() {
+        return lists.isEmpty();
+    }
+
+    /**
+     * Makes _this_ maplist immutable.
+     */
+    public void makeImmutable() {
+        for (Entry<L, List<R>> e : lists.entrySet())
+            lists.put(e.getKey(), Collections.unmodifiableList(e.getValue()));
+        lists = Collections.unmodifiableMap(lists);
+    }
+
+}