annotate src/clojure/lang/APersistentMap.java @ 10:ef7dbbd6452c

added clojure source goodness
author Robert McIntyre <rlm@mit.edu>
date Sat, 21 Aug 2010 06:25:44 -0400
parents
children
rev   line source
rlm@10 1 /**
rlm@10 2 * Copyright (c) Rich Hickey. All rights reserved.
rlm@10 3 * The use and distribution terms for this software are covered by the
rlm@10 4 * Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
rlm@10 5 * which can be found in the file epl-v10.html at the root of this distribution.
rlm@10 6 * By using this software in any fashion, you are agreeing to be bound by
rlm@10 7 * the terms of this license.
rlm@10 8 * You must not remove this notice, or any other, from this software.
rlm@10 9 **/
rlm@10 10
rlm@10 11 package clojure.lang;
rlm@10 12
rlm@10 13 import java.io.Serializable;
rlm@10 14 import java.util.*;
rlm@10 15
rlm@10 16 public abstract class APersistentMap extends AFn implements IPersistentMap, Map, Iterable, Serializable, MapEquivalence {
rlm@10 17 int _hash = -1;
rlm@10 18
rlm@10 19 public String toString(){
rlm@10 20 return RT.printString(this);
rlm@10 21 }
rlm@10 22
rlm@10 23 public IPersistentCollection cons(Object o){
rlm@10 24 if(o instanceof Map.Entry)
rlm@10 25 {
rlm@10 26 Map.Entry e = (Map.Entry) o;
rlm@10 27
rlm@10 28 return assoc(e.getKey(), e.getValue());
rlm@10 29 }
rlm@10 30 else if(o instanceof IPersistentVector)
rlm@10 31 {
rlm@10 32 IPersistentVector v = (IPersistentVector) o;
rlm@10 33 if(v.count() != 2)
rlm@10 34 throw new IllegalArgumentException("Vector arg to map conj must be a pair");
rlm@10 35 return assoc(v.nth(0), v.nth(1));
rlm@10 36 }
rlm@10 37
rlm@10 38 IPersistentMap ret = this;
rlm@10 39 for(ISeq es = RT.seq(o); es != null; es = es.next())
rlm@10 40 {
rlm@10 41 Map.Entry e = (Map.Entry) es.first();
rlm@10 42 ret = ret.assoc(e.getKey(), e.getValue());
rlm@10 43 }
rlm@10 44 return ret;
rlm@10 45 }
rlm@10 46
rlm@10 47 public boolean equals(Object obj){
rlm@10 48 return mapEquals(this, obj);
rlm@10 49 }
rlm@10 50
rlm@10 51 static public boolean mapEquals(IPersistentMap m1, Object obj){
rlm@10 52 if(m1 == obj) return true;
rlm@10 53 if(!(obj instanceof Map))
rlm@10 54 return false;
rlm@10 55 Map m = (Map) obj;
rlm@10 56
rlm@10 57 if(m.size() != m1.count() || m.hashCode() != m1.hashCode())
rlm@10 58 return false;
rlm@10 59
rlm@10 60 for(ISeq s = m1.seq(); s != null; s = s.next())
rlm@10 61 {
rlm@10 62 Map.Entry e = (Map.Entry) s.first();
rlm@10 63 boolean found = m.containsKey(e.getKey());
rlm@10 64
rlm@10 65 if(!found || !Util.equals(e.getValue(), m.get(e.getKey())))
rlm@10 66 return false;
rlm@10 67 }
rlm@10 68
rlm@10 69 return true;
rlm@10 70 }
rlm@10 71
rlm@10 72 public boolean equiv(Object obj){
rlm@10 73 if(!(obj instanceof Map))
rlm@10 74 return false;
rlm@10 75 if(obj instanceof IPersistentMap && !(obj instanceof MapEquivalence))
rlm@10 76 return false;
rlm@10 77
rlm@10 78 Map m = (Map) obj;
rlm@10 79
rlm@10 80 if(m.size() != size())
rlm@10 81 return false;
rlm@10 82
rlm@10 83 for(ISeq s = seq(); s != null; s = s.next())
rlm@10 84 {
rlm@10 85 Map.Entry e = (Map.Entry) s.first();
rlm@10 86 boolean found = m.containsKey(e.getKey());
rlm@10 87
rlm@10 88 if(!found || !Util.equiv(e.getValue(), m.get(e.getKey())))
rlm@10 89 return false;
rlm@10 90 }
rlm@10 91
rlm@10 92 return true;
rlm@10 93 }
rlm@10 94 public int hashCode(){
rlm@10 95 if(_hash == -1)
rlm@10 96 {
rlm@10 97 this._hash = mapHash(this);
rlm@10 98 }
rlm@10 99 return _hash;
rlm@10 100 }
rlm@10 101
rlm@10 102 static public int mapHash(IPersistentMap m){
rlm@10 103 int hash = 0;
rlm@10 104 for(ISeq s = m.seq(); s != null; s = s.next())
rlm@10 105 {
rlm@10 106 Map.Entry e = (Map.Entry) s.first();
rlm@10 107 hash += (e.getKey() == null ? 0 : e.getKey().hashCode()) ^
rlm@10 108 (e.getValue() == null ? 0 : e.getValue().hashCode());
rlm@10 109 }
rlm@10 110 return hash;
rlm@10 111 }
rlm@10 112
rlm@10 113 static public class KeySeq extends ASeq{
rlm@10 114 ISeq seq;
rlm@10 115
rlm@10 116 static public KeySeq create(ISeq seq){
rlm@10 117 if(seq == null)
rlm@10 118 return null;
rlm@10 119 return new KeySeq(seq);
rlm@10 120 }
rlm@10 121
rlm@10 122 private KeySeq(ISeq seq){
rlm@10 123 this.seq = seq;
rlm@10 124 }
rlm@10 125
rlm@10 126 private KeySeq(IPersistentMap meta, ISeq seq){
rlm@10 127 super(meta);
rlm@10 128 this.seq = seq;
rlm@10 129 }
rlm@10 130
rlm@10 131 public Object first(){
rlm@10 132 return ((Map.Entry) seq.first()).getKey();
rlm@10 133 }
rlm@10 134
rlm@10 135 public ISeq next(){
rlm@10 136 return create(seq.next());
rlm@10 137 }
rlm@10 138
rlm@10 139 public KeySeq withMeta(IPersistentMap meta){
rlm@10 140 return new KeySeq(meta, seq);
rlm@10 141 }
rlm@10 142 }
rlm@10 143
rlm@10 144 static public class ValSeq extends ASeq{
rlm@10 145 ISeq seq;
rlm@10 146
rlm@10 147 static public ValSeq create(ISeq seq){
rlm@10 148 if(seq == null)
rlm@10 149 return null;
rlm@10 150 return new ValSeq(seq);
rlm@10 151 }
rlm@10 152
rlm@10 153 private ValSeq(ISeq seq){
rlm@10 154 this.seq = seq;
rlm@10 155 }
rlm@10 156
rlm@10 157 private ValSeq(IPersistentMap meta, ISeq seq){
rlm@10 158 super(meta);
rlm@10 159 this.seq = seq;
rlm@10 160 }
rlm@10 161
rlm@10 162 public Object first(){
rlm@10 163 return ((Map.Entry) seq.first()).getValue();
rlm@10 164 }
rlm@10 165
rlm@10 166 public ISeq next(){
rlm@10 167 return create(seq.next());
rlm@10 168 }
rlm@10 169
rlm@10 170 public ValSeq withMeta(IPersistentMap meta){
rlm@10 171 return new ValSeq(meta, seq);
rlm@10 172 }
rlm@10 173 }
rlm@10 174
rlm@10 175
rlm@10 176 public Object invoke(Object arg1) throws Exception{
rlm@10 177 return valAt(arg1);
rlm@10 178 }
rlm@10 179
rlm@10 180 public Object invoke(Object arg1, Object notFound) throws Exception{
rlm@10 181 return valAt(arg1, notFound);
rlm@10 182 }
rlm@10 183
rlm@10 184 // java.util.Map implementation
rlm@10 185
rlm@10 186 public void clear(){
rlm@10 187 throw new UnsupportedOperationException();
rlm@10 188 }
rlm@10 189
rlm@10 190 public boolean containsValue(Object value){
rlm@10 191 return values().contains(value);
rlm@10 192 }
rlm@10 193
rlm@10 194 public Set entrySet(){
rlm@10 195 return new AbstractSet(){
rlm@10 196
rlm@10 197 public Iterator iterator(){
rlm@10 198 return APersistentMap.this.iterator();
rlm@10 199 }
rlm@10 200
rlm@10 201 public int size(){
rlm@10 202 return count();
rlm@10 203 }
rlm@10 204
rlm@10 205 public int hashCode(){
rlm@10 206 return APersistentMap.this.hashCode();
rlm@10 207 }
rlm@10 208
rlm@10 209 public boolean contains(Object o){
rlm@10 210 if(o instanceof Entry)
rlm@10 211 {
rlm@10 212 Entry e = (Entry) o;
rlm@10 213 Entry found = entryAt(e.getKey());
rlm@10 214 if(found != null && Util.equals(found.getValue(), e.getValue()))
rlm@10 215 return true;
rlm@10 216 }
rlm@10 217 return false;
rlm@10 218 }
rlm@10 219 };
rlm@10 220 }
rlm@10 221
rlm@10 222 public Object get(Object key){
rlm@10 223 return valAt(key);
rlm@10 224 }
rlm@10 225
rlm@10 226 public boolean isEmpty(){
rlm@10 227 return count() == 0;
rlm@10 228 }
rlm@10 229
rlm@10 230 public Set keySet(){
rlm@10 231 return new AbstractSet(){
rlm@10 232
rlm@10 233 public Iterator iterator(){
rlm@10 234 final Iterator mi = APersistentMap.this.iterator();
rlm@10 235
rlm@10 236 return new Iterator(){
rlm@10 237
rlm@10 238
rlm@10 239 public boolean hasNext(){
rlm@10 240 return mi.hasNext();
rlm@10 241 }
rlm@10 242
rlm@10 243 public Object next(){
rlm@10 244 Entry e = (Entry) mi.next();
rlm@10 245 return e.getKey();
rlm@10 246 }
rlm@10 247
rlm@10 248 public void remove(){
rlm@10 249 throw new UnsupportedOperationException();
rlm@10 250 }
rlm@10 251 };
rlm@10 252 }
rlm@10 253
rlm@10 254 public int size(){
rlm@10 255 return count();
rlm@10 256 }
rlm@10 257
rlm@10 258 public boolean contains(Object o){
rlm@10 259 return APersistentMap.this.containsKey(o);
rlm@10 260 }
rlm@10 261 };
rlm@10 262 }
rlm@10 263
rlm@10 264 public Object put(Object key, Object value){
rlm@10 265 throw new UnsupportedOperationException();
rlm@10 266 }
rlm@10 267
rlm@10 268 public void putAll(Map t){
rlm@10 269 throw new UnsupportedOperationException();
rlm@10 270 }
rlm@10 271
rlm@10 272 public Object remove(Object key){
rlm@10 273 throw new UnsupportedOperationException();
rlm@10 274 }
rlm@10 275
rlm@10 276 public int size(){
rlm@10 277 return count();
rlm@10 278 }
rlm@10 279
rlm@10 280 public Collection values(){
rlm@10 281 return new AbstractCollection(){
rlm@10 282
rlm@10 283 public Iterator iterator(){
rlm@10 284 final Iterator mi = APersistentMap.this.iterator();
rlm@10 285
rlm@10 286 return new Iterator(){
rlm@10 287
rlm@10 288
rlm@10 289 public boolean hasNext(){
rlm@10 290 return mi.hasNext();
rlm@10 291 }
rlm@10 292
rlm@10 293 public Object next(){
rlm@10 294 Entry e = (Entry) mi.next();
rlm@10 295 return e.getValue();
rlm@10 296 }
rlm@10 297
rlm@10 298 public void remove(){
rlm@10 299 throw new UnsupportedOperationException();
rlm@10 300 }
rlm@10 301 };
rlm@10 302 }
rlm@10 303
rlm@10 304 public int size(){
rlm@10 305 return count();
rlm@10 306 }
rlm@10 307 };
rlm@10 308 }
rlm@10 309
rlm@10 310 /*
rlm@10 311 // java.util.Collection implementation
rlm@10 312
rlm@10 313 public Object[] toArray(){
rlm@10 314 return RT.seqToArray(seq());
rlm@10 315 }
rlm@10 316
rlm@10 317 public boolean add(Object o){
rlm@10 318 throw new UnsupportedOperationException();
rlm@10 319 }
rlm@10 320
rlm@10 321 public boolean remove(Object o){
rlm@10 322 throw new UnsupportedOperationException();
rlm@10 323 }
rlm@10 324
rlm@10 325 public boolean addAll(Collection c){
rlm@10 326 throw new UnsupportedOperationException();
rlm@10 327 }
rlm@10 328
rlm@10 329 public void clear(){
rlm@10 330 throw new UnsupportedOperationException();
rlm@10 331 }
rlm@10 332
rlm@10 333 public boolean retainAll(Collection c){
rlm@10 334 throw new UnsupportedOperationException();
rlm@10 335 }
rlm@10 336
rlm@10 337 public boolean removeAll(Collection c){
rlm@10 338 throw new UnsupportedOperationException();
rlm@10 339 }
rlm@10 340
rlm@10 341 public boolean containsAll(Collection c){
rlm@10 342 for(Object o : c)
rlm@10 343 {
rlm@10 344 if(!contains(o))
rlm@10 345 return false;
rlm@10 346 }
rlm@10 347 return true;
rlm@10 348 }
rlm@10 349
rlm@10 350 public Object[] toArray(Object[] a){
rlm@10 351 if(a.length >= count())
rlm@10 352 {
rlm@10 353 ISeq s = seq();
rlm@10 354 for(int i = 0; s != null; ++i, s = s.rest())
rlm@10 355 {
rlm@10 356 a[i] = s.first();
rlm@10 357 }
rlm@10 358 if(a.length > count())
rlm@10 359 a[count()] = null;
rlm@10 360 return a;
rlm@10 361 }
rlm@10 362 else
rlm@10 363 return toArray();
rlm@10 364 }
rlm@10 365
rlm@10 366 public int size(){
rlm@10 367 return count();
rlm@10 368 }
rlm@10 369
rlm@10 370 public boolean isEmpty(){
rlm@10 371 return count() == 0;
rlm@10 372 }
rlm@10 373
rlm@10 374 public boolean contains(Object o){
rlm@10 375 if(o instanceof Map.Entry)
rlm@10 376 {
rlm@10 377 Map.Entry e = (Map.Entry) o;
rlm@10 378 Map.Entry v = entryAt(e.getKey());
rlm@10 379 return (v != null && Util.equal(v.getValue(), e.getValue()));
rlm@10 380 }
rlm@10 381 return false;
rlm@10 382 }
rlm@10 383 */
rlm@10 384 }