001    /*--------------------------------------------------------------------------+
002    $Id: HashedListMap.java 29486 2010-08-03 17:01:46Z juergens $
003    |                                                                          |
004    | Copyright 2005-2010 Technische Universitaet Muenchen                     |
005    |                                                                          |
006    | Licensed under the Apache License, Version 2.0 (the "License");          |
007    | you may not use this file except in compliance with the License.         |
008    | You may obtain a copy of the License at                                  |
009    |                                                                          |
010    |    http://www.apache.org/licenses/LICENSE-2.0                            |
011    |                                                                          |
012    | Unless required by applicable law or agreed to in writing, software      |
013    | distributed under the License is distributed on an "AS IS" BASIS,        |
014    | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
015    | See the License for the specific language governing permissions and      |
016    | limitations under the License.                                           |
017    +--------------------------------------------------------------------------*/
018    package edu.tum.cs.commons.collections;
019    
020    import java.util.ArrayList;
021    import java.util.Collection;
022    import java.util.HashMap;
023    import java.util.List;
024    import java.util.Map;
025    import java.util.Set;
026    
027    /**
028     * This class defines a mapping from on item to a list of items.
029     * 
030     * @author Florian Deissenboeck
031     * @author $Author: juergens $
032     * 
033     * @version $Revision: 29486 $
034     * @levd.rating GREEN Hash: 9C7E831BF9AF4EA0F4F0871B02C36449
035     */
036    public class HashedListMap<K, I> {
037    
038            /** The actual map. */
039            private final Map<K, List<I>> entries;
040    
041            /**
042             * Create new hashed list map.
043             */
044            public HashedListMap() {
045                    entries = new HashMap<K, List<I>>();
046            }
047    
048            /**
049             * Create new hashed list map with a specified map.
050             */
051            public HashedListMap(Map<K, List<I>> map) {
052                    entries = map;
053            }
054    
055            /** Copy constructor. */
056            public HashedListMap(HashedListMap<K, I> other) {
057                    this();
058                    addAll(other);
059            }
060    
061            /**
062             * Create an empty list for a key. This overrides a previosly mapped list.
063             */
064            public List<I> createList(K key) {
065                    List<I> list = new ArrayList<I>();
066                    entries.put(key, list);
067                    return list;
068            }
069    
070            /**
071             * Get list for key.
072             * 
073             * 
074             * @return the list or <code>null</code>
075             */
076            public List<I> getList(K key) {
077                    return entries.get(key);
078            }
079    
080            /**
081             * Add an item to the list identified by a key.
082             * 
083             */
084            public void add(K key, I item) {
085                    ensureListExists(key).add(item);
086            }
087    
088            /**
089             * Add all items to the list identified by a key.
090             * 
091             */
092            public void addAll(K key, Collection<I> items) {
093                    ensureListExists(key).addAll(items);
094            }
095    
096            /** Adds all elements from another hashed list map. */
097            public void addAll(HashedListMap<K, I> other) {
098                    for (K key : other.getKeys()) {
099                            List<I> list = other.getList(key);
100                            if (list != null) {
101                                    addAll(key, list);
102                            }
103                    }
104            }
105    
106            /**
107             * Check if a list is present for a given key.
108             */
109            public boolean containsList(K key) {
110                    return entries.containsKey(key);
111            }
112    
113            /**
114             * Removes the list stored for a key.
115             */
116            public void removeList(K key) {
117                    entries.remove(key);
118            }
119    
120            /**
121             * Removes the lists stored for a collection of keys
122             */
123            public void removeAllLists(Collection<K> keys) {
124                    for (K key : keys) {
125                            removeList(key);
126                    }
127            }
128    
129            /** Get keys. */
130            public Set<K> getKeys() {
131                    return entries.keySet();
132            }
133    
134            /** Return all values from all lists. */
135            public List<I> getValues() {
136                    List<I> result = new ArrayList<I>();
137                    for (List<I> values : entries.values()) {
138                            result.addAll(values);
139                    }
140                    return result;
141            }
142    
143            /**
144             * Checks if all lists stored in the map are empty. This returns true if
145             * {@link #getValues()} returns an empty list.
146             */
147            public boolean areAllListsEmpty() {
148                    for (K key : entries.keySet()) {
149                            List<I> list = entries.get(key);
150                            if (!list.isEmpty()) {
151                                    return false;
152                            }
153                    }
154                    return true;
155            }
156    
157            /**
158             * Clear map. This removes all lists.
159             */
160            public void clear() {
161                    entries.clear();
162            }
163    
164            /**
165             * Ensures that a list exists for a given key.
166             */
167            private List<I> ensureListExists(K item) {
168    
169                    if (!entries.containsKey(item)) {
170                            return createList(item);
171                    }
172                    return entries.get(item);
173            }
174    
175            /**
176             * Converts the {@link HashedListMap} to a map with arrays
177             * 
178             * @param type
179             *            Type of the target array
180             */
181            public Map<K, I[]> listsToArrays(Class<I> type) {
182                    Map<K, I[]> map = new HashMap<K, I[]>();
183                    for (K key : getKeys()) {
184                            map.put(key, CollectionUtils.toArray(getList(key), type));
185                    }
186                    return map;
187            }
188    }