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