001package components.map; 002 003import java.util.HashMap; 004import java.util.Iterator; 005import java.util.NoSuchElementException; 006import java.util.Set; 007 008/** 009 * {@code Map} represented as a {@link java.util.Map java.util.Map} with 010 * implementations of primary methods. 011 * 012 * @param <K> 013 * type of {@code Map} domain (key) entries 014 * @param <V> 015 * type of {@code Map} range (associated value) entries 016 * @correspondence this = [value of $this] 017 */ 018public class Map1L<K, V> extends MapSecondary<K, V> { 019 020 /* 021 * Private members -------------------------------------------------------- 022 */ 023 024 /** 025 * Representation of {@code this}. 026 */ 027 private java.util.Map<K, V> rep; 028 029 /** 030 * Creator of initial representation. 031 */ 032 private void createNewRep() { 033 this.rep = new HashMap<K, V>(); 034 } 035 036 /* 037 * Constructors ----------------------------------------------------------- 038 */ 039 040 /** 041 * No-argument constructor. 042 */ 043 public Map1L() { 044 this.createNewRep(); 045 } 046 047 /* 048 * Standard methods ------------------------------------------------------- 049 */ 050 051 @SuppressWarnings("unchecked") 052 @Override 053 public final Map<K, V> newInstance() { 054 try { 055 return this.getClass().getConstructor().newInstance(); 056 } catch (ReflectiveOperationException e) { 057 throw new AssertionError( 058 "Cannot construct object of type " + this.getClass()); 059 } 060 } 061 062 @Override 063 public final void clear() { 064 this.createNewRep(); 065 } 066 067 @Override 068 public final void transferFrom(Map<K, V> source) { 069 assert source != null : "Violation of: source is not null"; 070 assert source != this : "Violation of: source is not this"; 071 assert source instanceof Map1L<?, ?> 072 : "Violation of: source is of dynamic type Map1L<?,?>"; 073 /* 074 * This cast cannot fail since the assert above would have stopped 075 * execution in that case: source must be of dynamic type Map2<?,?>, and 076 * the ?,? must be K,V or the call would not have compiled. 077 */ 078 Map1L<K, V> localSource = (Map1L<K, V>) source; 079 this.rep = localSource.rep; 080 localSource.createNewRep(); 081 } 082 083 /* 084 * Kernel methods --------------------------------------------------------- 085 */ 086 087 @Override 088 public final void add(K key, V value) { 089 assert key != null : "Violation of: key is not null"; 090 assert value != null : "Violation of: value is not null"; 091 assert !this.hasKey(key) : "Violation of: key is not in DOMAIN(this)"; 092 this.rep.put(key, value); 093 } 094 095 @Override 096 public final Map.Pair<K, V> remove(K key) { 097 assert key != null : "Violation of: key is not null"; 098 assert this.hasKey(key) : "Violation of: key is in DOMAIN(this)"; 099 /* 100 * The following "obvious" code is incorrect because it creates an alias 101 * where one is not specified in the contract (because no alias is 102 * needed). This is a design flaw in java.util.Map that means Map1L is 103 * not a competitive implementation of MapKernel when assertion-checking 104 * is disabled. 105 */ 106 // return new SimplePair<K, V>(key, this.rep.remove(key)); 107 /* 108 * Note: null will never be returned, but we still need to initialize. 109 */ 110 K keyRemoved = null; 111 Set<K> keys = this.rep.keySet(); 112 for (K x : keys) { 113 if (x.equals(key)) { 114 keyRemoved = x; 115 break; 116 } 117 } 118 V valueRemoved = this.rep.remove(keyRemoved); 119 return new SimplePair<K, V>(keyRemoved, valueRemoved); 120 } 121 122 @Override 123 public final Pair<K, V> removeAny() { 124 assert this.size() > 0 : "Violation of: this /= empty_set"; 125 Iterator<java.util.Map.Entry<K, V>> it = this.rep.entrySet().iterator(); 126 java.util.Map.Entry<K, V> entry = it.next(); 127 it.remove(); 128 return new SimplePair<K, V>(entry.getKey(), entry.getValue()); 129 } 130 131 @Override 132 public final V value(K key) { 133 assert key != null : "Violation of: key is not null"; 134 assert this.hasKey(key) : "Violation of: key is in DOMAIN(this)"; 135 return this.rep.get(key); 136 } 137 138 @Override 139 public final boolean hasKey(K key) { 140 assert key != null : "Violation of: key is not null"; 141 return this.rep.containsKey(key); 142 } 143 144 @Override 145 public final int size() { 146 return this.rep.size(); 147 } 148 149 @Override 150 public final Iterator<Pair<K, V>> iterator() { 151 return new Map1LIterator(); 152 } 153 154 /** 155 * Implementation of {@code Iterator} interface for {@code Map1L}. 156 */ 157 private final class Map1LIterator implements Iterator<Pair<K, V>> { 158 159 /** 160 * Representation iterator. 161 */ 162 private final Iterator<java.util.Map.Entry<K, V>> iterator; 163 164 /** 165 * No-argument constructor. 166 */ 167 private Map1LIterator() { 168 this.iterator = Map1L.this.rep.entrySet().iterator(); 169 } 170 171 @Override 172 public boolean hasNext() { 173 return this.iterator.hasNext(); 174 } 175 176 @Override 177 public Pair<K, V> next() { 178 assert this.hasNext() : "Violation of: ~this.unseen /= <>"; 179 if (!this.hasNext()) { 180 /* 181 * Exception is supposed to be thrown in this case, but with 182 * assertion-checking enabled it cannot happen because of assert 183 * above. 184 */ 185 throw new NoSuchElementException(); 186 } 187 java.util.Map.Entry<K, V> entry = this.iterator.next(); 188 return new SimplePair<K, V>(entry.getKey(), entry.getValue()); 189 } 190 191 @Override 192 public void remove() { 193 throw new UnsupportedOperationException("remove operation not supported"); 194 } 195 196 } 197 198 /* 199 * Other methods (overridden for performance reasons) --------------------- 200 */ 201 202 @Override 203 public final V replaceValue(K key, V value) { 204 assert key != null : "Violation of: key is not null"; 205 assert value != null : "Violation of: value is not null"; 206 assert this.hasKey(key) : "Violation of: key is in DOMAIN(this)"; 207 return this.rep.put(key, value); 208 } 209 210}