1 28 29 package org.jruby.util; 30 31 import java.util.AbstractCollection ; 32 import java.util.AbstractSet ; 33 import java.util.Collection ; 34 import java.util.Iterator ; 35 import java.util.Map ; 36 import java.util.Set ; 37 38 45 46 abstract class GenericMap implements Map { 47 protected int size; 48 49 public int size() { 50 return size; 51 } 52 53 public boolean isEmpty() { 54 return size() == 0; 55 } 56 57 protected int keyHash(Object key) { 58 if (key == null) 59 return 0; 60 else 61 return key.hashCode(); 62 } 63 64 protected boolean keyEquals(Object containedKey, Object givenKey) { 65 if (containedKey == null) 66 return givenKey == null; 67 else 68 return containedKey.equals(givenKey); 69 } 70 71 protected int valueHash(Object value) { 72 if (value == null) 73 return 0; 74 else 75 return value.hashCode(); 76 } 77 78 protected boolean valueEquals(Object value1, Object value2) { 79 if (value1 == null) 80 return value2 == null; 81 else 82 return value1.equals(value2); 83 } 84 85 abstract class Entry implements Map.Entry { 86 public int hashCode() { 87 return keyHash(getKey()) ^ valueHash(getValue()); 88 } 89 90 public boolean equals(Object other) { 91 if (other instanceof Map.Entry ) { 92 Map.Entry ent = (Map.Entry ) other; 93 return keyEquals(getKey(), ent.getKey()) 94 && valueEquals(getValue(), ent.getValue()); 95 } else { 96 return false; 97 } 98 } 99 100 } 101 102 public void putAll(Map other) { 103 if (other == this) 104 return; 105 106 Iterator it = other.entrySet().iterator(); 107 while (it.hasNext()) { 108 Map.Entry entry = (Map.Entry ) it.next(); 109 put(entry.getKey(), entry.getValue()); 110 } 111 } 112 113 protected abstract Iterator entryIterator(); 114 115 protected Iterator keyIterator() { 116 return new KeyIterator(); 117 } 118 119 protected Iterator valueIterator() { 120 return new ValueIterator(); 121 } 122 123 abstract class KeyOrValueIterator implements Iterator { 124 Iterator iter = entryIterator(); 125 126 public boolean hasNext() { 127 return iter.hasNext(); 128 } 129 130 protected Map.Entry nextEntry() { 131 return (Map.Entry ) iter.next(); 132 } 133 134 public void remove() { 135 throw new UnsupportedOperationException (); 136 } 137 138 } 139 140 class KeyIterator extends KeyOrValueIterator { 141 public Object next() { 142 return nextEntry().getKey(); 143 } 144 } 145 146 class ValueIterator extends KeyOrValueIterator { 147 public Object next() { 148 return nextEntry().getValue(); 149 } 150 } 151 152 157 158 private static Object [] toArray(Object [] arr, int size, Iterator it) { 159 Object [] out; 160 161 if (arr != null && arr.length >= size) { 162 out = arr; 163 } else if (arr == null) { 164 out = new Object [size]; 165 } else { 166 out = (Object []) java.lang.reflect.Array.newInstance(arr.getClass() 167 .getComponentType(), size); 168 } 169 170 for (int i = 0; i < size; i++) { 171 out[i] = it.next(); 172 } 173 174 if (out.length > size) 175 out[size] = null; 176 177 return out; 178 } 179 180 public Collection values() { 181 return new AbstractCollection () { 182 public Iterator iterator() { 183 return valueIterator(); 184 } 185 186 public int size() { 187 return GenericMap.this.size(); 188 } 189 190 public Object [] toArray(Object [] arr) { 191 return GenericMap.toArray(arr, size(), iterator()); 192 } 193 }; 194 } 195 196 public Set keySet() { 197 return new AbstractSet () { 198 public Iterator iterator() { 199 return keyIterator(); 200 } 201 202 public int size() { 203 return GenericMap.this.size(); 204 } 205 206 public Object [] toArray(Object [] arr) { 207 return GenericMap.toArray(arr, size(), iterator()); 208 } 209 }; 210 } 211 212 public int hashCode() { 213 int code = 0; 214 Iterator it = entryIterator(); 215 while (it.hasNext()) { 216 code += it.next().hashCode(); 217 } 218 return code; 219 } 220 221 public boolean equals(Object other) { 222 if (other instanceof Map ) { 223 Map map = (Map ) other; 224 225 if (map.size() != size()) 226 return false; 227 228 Iterator it = entryIterator(); 229 while (it.hasNext()) { 230 Entry ent = (Entry) it.next(); 231 Object key = ent.getKey(); 232 Object val = ent.getValue(); 233 234 if (map.containsKey(key)) { 235 Object otherVal = map.get(key); 236 if (!valueEquals(val, otherVal)) 237 return false; 238 } 239 } 240 return true; 241 } 242 return false; 243 } 244 245 public Set entrySet() { 246 return new AbstractSet () { 247 public Iterator iterator() { 248 return entryIterator(); 249 } 250 251 public int size() { 252 return size; 253 } 254 255 public Object [] toArray(Object [] arr) { 256 return GenericMap.toArray(arr, size(), iterator()); 257 } 258 }; 259 } 260 261 262 public boolean containsValue(Object value) { 263 Iterator it = valueIterator(); 264 while (it.hasNext()) { 265 if (valueEquals(value, it.next())) 266 return true; 267 } 268 return false; 269 } 270 271 public boolean containsKey(Object key) { 272 return get(key) != null; 273 } 274 } 275 | Popular Tags |