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