View Javadoc
1   package org.opentrafficsim.base.immutablecollections;
2   
3   import java.io.Serializable;
4   import java.util.ConcurrentModificationException;
5   import java.util.Map;
6   import java.util.Objects;
7   import java.util.Set;
8   import java.util.function.BiConsumer;
9   
10  /**
11   * A Map interface without the methods that can change it. The constructor of the ImmutableMap needs to be given an initial Map.
12   * <p>
13   * Copyright (c) 2013-2016 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
14   * BSD-style license. See <a href="http://opentrafficsim.org/docs/license.html">OpenTrafficSim License</a>.
15   * </p>
16   * $LastChangedDate: 2015-07-24 02:58:59 +0200 (Fri, 24 Jul 2015) $, @version $Revision: 1147 $, by $Author: averbraeck $,
17   * initial version May 7, 2016 <br>
18   * @author <a href="http://www.tbm.tudelft.nl/averbraeck">Alexander Verbraeck</a>
19   * @author <a href="http://www.tudelft.nl/pknoppers">Peter Knoppers</a>
20   * @author <a href="http://www.transport.citg.tudelft.nl">Wouter Schakel</a>
21   * @param <K> the key type of content of this Map
22   * @param <V> the value type of content of this Map
23   */
24  public interface ImmutableMap<K, V> extends Serializable
25  {
26      /**
27       * Returns the number of elements in this immutable collection. If this immutable collection contains more than
28       * <tt>Integer.MAX_VALUE</tt> elements, returns <tt>Integer.MAX_VALUE</tt>.
29       * @return the number of elements in this immutable collection
30       */
31      int size();
32  
33      /**
34       * Returns <tt>true</tt> if this immutable collection contains no elements.
35       * @return <tt>true</tt> if this immutable collection contains no elements
36       */
37      boolean isEmpty();
38  
39      /**
40       * Returns <tt>true</tt> if this map contains a mapping for the specified key. More formally, returns <tt>true</tt> if and
41       * only if this map contains a mapping for a key <tt>k</tt> such that <tt>(key==null ? k==null : key.equals(k))</tt>. (There
42       * can be at most one such mapping.)
43       * @param key key whose presence in this map is to be tested
44       * @return <tt>true</tt> if this map contains a mapping for the specified key
45       * @throws ClassCastException if the key is of an inappropriate type for this map
46       * @throws NullPointerException if the specified key is null and this map does not permit null keys
47       */
48      boolean containsKey(Object key);
49  
50      /**
51       * Returns <tt>true</tt> if this map maps one or more keys to the specified value. More formally, returns <tt>true</tt> if
52       * and only if this map contains at least one mapping to a value <tt>v</tt> such that
53       * <tt>(value==null ? v==null : value.equals(v))</tt>. This operation will probably require time linear in the map size for
54       * most implementations of the <tt>Map</tt> interface.
55       * @param value value whose presence in this map is to be tested
56       * @return <tt>true</tt> if this map maps one or more keys to the specified value
57       * @throws ClassCastException if the value is of an inappropriate type for this map
58       * @throws NullPointerException if the specified value is null and this map does not permit null values
59       */
60      boolean containsValue(Object value);
61  
62      /**
63       * Returns the value to which the specified key is mapped, or {@code null} if this map contains no mapping for the key.
64       * <p>
65       * More formally, if this map contains a mapping from a key {@code k} to a value {@code v} such that
66       * {@code (key==null ? k==null : key.equals(k))}, then this method returns {@code v}; otherwise it returns {@code null}.
67       * (There can be at most one such mapping.)
68       * <p>
69       * If this map permits null values, then a return value of {@code null} does not <i>necessarily</i> indicate that the map
70       * contains no mapping for the key; it's also possible that the map explicitly maps the key to {@code null}. The
71       * {@link #containsKey containsKey} operation may be used to distinguish these two cases.
72       * @param key the key whose associated value is to be returned
73       * @return the value to which the specified key is mapped, or {@code null} if this map contains no mapping for the key
74       * @throws ClassCastException if the key is of an inappropriate type for this map
75       * @throws NullPointerException if the specified key is null and this map does not permit null keys
76       */
77      V get(Object key);
78  
79      /**
80       * Returns a {@link Set} view of the keys contained in this map.
81       * @return an immutable set of the keys contained in this map
82       */
83      ImmutableSet<K> keySet();
84  
85      /**
86       * Returns a {@link ImmutableCollection} view of the values contained in this map.
87       * @return an immutable collection view of the values contained in this map
88       */
89      ImmutableCollection<V> values();
90  
91      /**
92       * Returns the value to which the specified key is mapped, or {@code defaultValue} if this map contains no mapping for the
93       * key. The default implementation makes no guarantees about synchronization or atomicity properties of this method. Any
94       * implementation providing atomicity guarantees must override this method and document its concurrency properties.
95       * @param key the key whose associated value is to be returned
96       * @param defaultValue the default mapping of the key
97       * @return the value to which the specified key is mapped, or {@code defaultValue} if this map contains no mapping for the
98       *         key
99       * @throws ClassCastException if the key is of an inappropriate type for this map
100      * @throws NullPointerException if the specified key is null and this map does not permit null keys
101      */
102     default V getOrDefault(Object key, V defaultValue)
103     {
104         V v = get(key);
105         return ((v != null) || containsKey(key)) ? v : defaultValue;
106     }
107 
108     /**
109      * Performs the given action for each entry in this map until all entries have been processed or the action throws an
110      * exception. Unless otherwise specified by the implementing class, actions are performed in the order of entry set
111      * iteration (if an iteration order is specified.) Exceptions thrown by the action are relayed to the caller. The default
112      * implementation makes no guarantees about synchronization or atomicity properties of this method. Any implementation
113      * providing atomicity guarantees must override this method and document its concurrency properties.
114      * @param action The action to be performed for each entry
115      * @throws NullPointerException if the specified action is null
116      * @throws ConcurrentModificationException if an entry is found to be removed during iteration
117      */
118     default void forEach(BiConsumer<? super K, ? super V> action)
119     {
120         Objects.requireNonNull(action);
121         for (Map.Entry<K, V> entry : toMap().entrySet())
122         {
123             K k;
124             V v;
125             try
126             {
127                 k = entry.getKey();
128                 v = entry.getValue();
129             }
130             catch (IllegalStateException ise)
131             {
132                 // this usually means the entry is no longer in the map.
133                 throw new ConcurrentModificationException(ise);
134             }
135             action.accept(k, v);
136         }
137     }
138 
139     /**
140      * Returns a modifiable copy of this immutable list.
141      * @return a modifiable copy of this immutable list.
142      */
143     Map<K, V> toMap();
144 
145     /**
146      * Force to redefine equals for the implementations of immutable collection classes.
147      * @param obj the object to compare this collection with
148      * @return whether the objects are equal
149      */
150     boolean equals(final Object obj);
151 
152     /**
153      * Force to redefine hashCode for the implementations of immutable collection classes.
154      * @return the calculated hashCode
155      */
156     int hashCode();
157 
158     /**
159      * Return whether the internal storage is a wrapped pointer to the original map. If true, this means that anyone holding a
160      * pointer to this data structure can still change it. The users of the ImmutableMap itself can, however, not make any
161      * changes.
162      * @return boolean; whether the internal storage is a wrapped pointer to the original map
163      */
164     boolean isWrap();
165 
166     /**
167      * Return whether the internal storage is a (shallow) copy of the original map. If true, this means that anyone holding a
168      * pointer to the original of the data structure can not change it anymore. Nor can the users of the ImmutableMap itself
169      * make any changes.
170      * @return boolean; whether the internal storage is a safe copy of the original map
171      */
172     default boolean isCopy()
173     {
174         return !isWrap();
175     }
176 
177 }