001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.commons.collections4; 018 019import java.util.Collection; 020import java.util.Map; 021import java.util.Map.Entry; 022import java.util.Set; 023 024/** 025 * Defines a map that holds a collection of values against each key. 026 * <p> 027 * A {@code MultiValuedMap} is a Map with slightly different semantics: 028 * <ul> 029 * <li>Putting a value into the map will add the value to a {@link Collection} at that key.</li> 030 * <li>Getting a value will return a {@link Collection}, holding all the values put to that key.</li> 031 * </ul> 032 * <p> 033 * For example: 034 * <pre> 035 * MultiValuedMap<K, String> map = new MultiValuedHashMap<K, String>(); 036 * map.put(key, "A"); 037 * map.put(key, "B"); 038 * map.put(key, "C"); 039 * Collection<String> coll = map.get(key); 040 * </pre> 041 * <p> 042 * <code>coll</code> will be a collection containing "A", "B", "C". 043 * <p> 044 * 045 * @param <K> the type of the keys in this map 046 * @param <V> the type of the values in this map 047 * @since 4.1 048 */ 049public interface MultiValuedMap<K, V> { 050 // Query operations 051 052 /** 053 * Gets the total size of the map. 054 * <p> 055 * Implementations would return the total size of the map which is the count 056 * of the values from all keys. 057 * 058 * @return the total size of the map 059 */ 060 int size(); 061 062 /** 063 * Returns {@code true} if this map contains no key-value mappings. 064 * 065 * @return {@code true} if this map contains no key-value mappings 066 */ 067 boolean isEmpty(); 068 069 /** 070 * Returns {@code true} if this map contains a mapping for the specified 071 * key. More formally, returns {@code true} if and only if this map contains 072 * a mapping for a key {@code k} such that {@code (key==null ? k==null : key.equals(k))}. 073 * (There can be at most one such mapping.) 074 * 075 * @param key key whose presence in this map is to be tested 076 * @return true if this map contains a mapping for the specified key 077 * @throws NullPointerException if the specified key is null and this map 078 * does not permit null keys (optional) 079 */ 080 boolean containsKey(Object key); 081 082 /** 083 * Checks whether the map contains at least one mapping for the specified value. 084 * 085 * @param value the value to search for 086 * @return true if the map contains the value 087 * @throws NullPointerException if the value is null and null values are not supported 088 * by the used collection types (optional) 089 */ 090 boolean containsValue(Object value); 091 092 /** 093 * Checks whether the map contains a mapping for the specified key and value. 094 * 095 * @param key the key to search for 096 * @param value the value to search for 097 * @return true if the map contains the value 098 */ 099 boolean containsMapping(Object key, Object value); 100 101 /** 102 * Returns a view collection of the values associated with the specified key. 103 * <p> 104 * This method will return an <b>empty</b> collection if {@link #containsKey(Object)} 105 * returns {@code false}. Changes to the returned collection will update the underlying 106 * {@code MultiValuedMap} and vice-versa. 107 * 108 * @param key the key to retrieve 109 * @return the {@code Collection} of values, implementations should 110 * return an empty collection for no mapping 111 * @throws NullPointerException if the key is null and null keys are invalid (optional) 112 */ 113 Collection<V> get(K key); 114 115 // Modification operations 116 117 /** 118 * Adds a key-value mapping to this multi-valued map. 119 * <p> 120 * Unlike a normal {@code Map} the previous value is not replaced. 121 * Instead the new value is added to the collection stored against the key. 122 * Depending on the collection type used, duplicate key-value mappings may 123 * be allowed. 124 * <p> 125 * The method will return {@code true} if the size of the multi-valued map 126 * has been increased because of this operation. 127 * 128 * @param key the key to store against 129 * @param value the value to add to the collection at the key 130 * @return true if the map changed as a result of this put operation, or false 131 * if the map already contained the key-value mapping and the collection 132 * type does not allow duplicate values, e.g. when using a Set 133 * @throws UnsupportedOperationException if the put operation is not supported by 134 * this multi-valued map, e.g. if it is unmodifiable 135 * @throws NullPointerException if the key or value is null and null is invalid (optional) 136 * @throws IllegalArgumentException if some aspect of the specified key or value prevents 137 * it from being stored in this multi-valued map 138 */ 139 boolean put(K key, V value); 140 141 /** 142 * Adds a mapping to the specified key for all values contained in the given Iterable. 143 * 144 * @param key the key to store against 145 * @param values the values to add to the collection at the key, may not be null 146 * @return true if the map changed as a result of this operation 147 * @throws NullPointerException if the specified iterable is null, or if this map 148 * does not permit null keys or values, and the specified key or values contain 149 * null (optional) 150 */ 151 boolean putAll(K key, Iterable<? extends V> values); 152 153 /** 154 * Copies all mappings from the specified map to this multi-valued map 155 * (optional operation). 156 * <p> 157 * The effect of this call is equivalent to that of calling 158 * {@link #put(Object,Object) put(k, v)} on this map once for each mapping 159 * from key {@code k} to value {@code v} in the specified map. 160 * <p> 161 * The behavior of this operation is undefined if the specified map is modified 162 * while the operation is in progress. 163 * 164 * @param map mappings to be stored in this map, may not be null 165 * @return true if the map changed as a result of this operation 166 * @throws UnsupportedOperationException if the {@code putAll} operation is 167 * not supported by this map 168 * @throws NullPointerException if the specified map is null, or if this map 169 * does not permit null keys or values, and the specified map 170 * contains null keys or values (optional) 171 * @throws IllegalArgumentException if some property of a key or value in 172 * the specified map prevents it from being stored in this map 173 */ 174 boolean putAll(Map<? extends K, ? extends V> map); 175 176 /** 177 * Copies all mappings from the specified map to this multi-valued map 178 * (optional operation). 179 * <p> 180 * The effect of this call is equivalent to that of calling 181 * {@link #put(Object,Object) put(k, v)} on this map once for each 182 * mapping from key {@code k} to value {@code v} in the specified map. 183 * <p> 184 * The behavior of this operation is undefined if the specified map is modified 185 * while the operation is in progress. 186 * 187 * @param map mappings to be stored in this map, may not be null 188 * @return true if the map changed as a result of this operation 189 * @throws UnsupportedOperationException if the {@code putAll} operation is 190 * not supported by this map 191 * @throws NullPointerException if the specified map is null, or if this map 192 * does not permit null keys or values, and the specified map 193 * contains null keys or values (optional) 194 * @throws IllegalArgumentException if some property of a key or value in 195 * the specified map prevents it from being stored in this map 196 */ 197 boolean putAll(MultiValuedMap<? extends K, ? extends V> map); 198 199 /** 200 * Removes all values associated with the specified key. 201 * <p> 202 * The returned collection <i>may</i> be modifiable, but updates will not be propagated 203 * to this multi-valued map. In case no mapping was stored for the specified 204 * key, an empty, unmodifiable collection will be returned. 205 * 206 * @param key the key to remove values from 207 * @return the values that were removed 208 * @throws UnsupportedOperationException if the map is unmodifiable 209 * @throws NullPointerException if the key is null and null keys are invalid (optional) 210 */ 211 Collection<V> remove(Object key); 212 213 /** 214 * Removes a key-value mapping from the map. 215 * <p> 216 * The item is removed from the collection mapped to the specified key. 217 * Other values attached to that key are unaffected. 218 * <p> 219 * If the last value for a key is removed, implementations typically return 220 * an empty collection from a subsequent <code>get(Object)</code>. 221 * 222 * @param key the key to remove from 223 * @param item the item to remove 224 * @return true if the mapping was removed, false otherwise 225 * @throws UnsupportedOperationException if the map is unmodifiable 226 * @throws NullPointerException if the key or value is null and null is invalid (optional) 227 */ 228 boolean removeMapping(Object key, Object item); 229 230 /** 231 * Removes all of the mappings from this map (optional operation). 232 * <p> 233 * The map will be empty after this call returns. 234 * 235 * @throws UnsupportedOperationException if the map is unmodifiable 236 */ 237 void clear(); 238 239 // Views 240 241 /** 242 * Returns a {@link Collection} view of the mappings contained in this multi-valued map. 243 * <p> 244 * The collection is backed by the map, so changes to the map are reflected 245 * in the collection, and vice-versa. 246 * 247 * @return a set view of the mappings contained in this map 248 */ 249 Collection<Entry<K, V>> entries(); 250 251 /** 252 * Returns a {@link MultiSet} view of the keys contained in this multi-valued map. 253 * <p> 254 * The {@link MultiSet#getCount(Object)} method of the returned multiset will give 255 * the same result a calling {@code get(Object).size()} for the same key. 256 * <p> 257 * This multiset is backed by the map, so any changes in the map are reflected in 258 * the multiset. 259 * 260 * @return a multiset view of the keys contained in this map 261 */ 262 MultiSet<K> keys(); 263 264 /** 265 * Returns a {@link Set} view of the keys contained in this multi-valued map. 266 * <p> 267 * The set is backed by the map, so changes to the map are reflected 268 * in the set, and vice-versa. 269 * <p> 270 * If the map is modified while an iteration over the set is in 271 * progress (except through the iterator's own {@code remove} operation), 272 * the result of the iteration is undefined. The set supports element 273 * removal, which removes the corresponding mapping from the map, via the 274 * {@code Iterator.remove}, {@code Set.remove}, {@code removeAll}, 275 * {@code retainAll}, and {@code clear} operations. It does not support 276 * the {@code add} or {@code addAll} operations. 277 * 278 * @return a set view of the keys contained in this map 279 */ 280 Set<K> keySet(); 281 282 /** 283 * Gets a {@link Collection} view of all values contained in this multi-valued map. 284 * <p> 285 * Implementations typically return a collection containing the combination 286 * of values from all keys. 287 * 288 * @return a collection view of the values contained in this multi-valued map 289 */ 290 Collection<V> values(); 291 292 /** 293 * Returns a view of this multi-valued map as a {@code Map} from each distinct 294 * key to the non-empty collection of that key's associated values. 295 * <p> 296 * Note that {@code this.asMap().get(k)} is equivalent to {@code this.get(k)} 297 * only when {@code k} is a key contained in the multi-valued map; otherwise it 298 * returns {@code null} as opposed to an empty collection. 299 * <p> 300 * Changes to the returned map or the collections that serve as its values 301 * will update the underlying multi-valued map, and vice versa. The map does 302 * not support {@code put} or {@code putAll}, nor do its entries support 303 * {@link java.util.Map.Entry#setValue(Object) setValue}. 304 * 305 * @return a map view of the mappings in this multi-valued map 306 */ 307 Map<K, Collection<V>> asMap(); 308 309 // Iterators 310 311 /** 312 * Obtains a <code>MapIterator</code> over this multi-valued map. 313 * <p> 314 * A map iterator is an efficient way of iterating over maps. There is no 315 * need to access the entries collection or use {@code Map.Entry} objects. 316 * 317 * @return a map iterator 318 */ 319 MapIterator<K, V> mapIterator(); 320 321}