All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.pure4j.collections.APersistentMap Maven / Gradle / Ivy

There is a newer version: 0.3.1
Show newest version
/**
 *   Copyright (c) Rich Hickey. All rights reserved.
 *   The use and distribution terms for this software are covered by the
 *   Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
 *   which can be found in the file epl-v10.html at the root of this distribution.
 *   By using this software in any fashion, you are agreeing to be bound by
 * 	 the terms of this license.
 *   You must not remove this notice, or any other, from this software.
 **/

package org.pure4j.collections;

import java.io.Serializable;
import java.util.Collection;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

import org.pure4j.Pure4J;
import org.pure4j.annotations.immutable.IgnoreImmutableTypeCheck;
import org.pure4j.annotations.pure.Enforcement;
import org.pure4j.annotations.pure.Pure;

public abstract class APersistentMap implements IPersistentMap,
		Map, Iterable>, Serializable {
	
	private static final long serialVersionUID = 1L;
	
	@IgnoreImmutableTypeCheck
	int _hasheq = -1;
	
	public APersistentMap() {
	}
	
	public APersistentMap(ISeq> elems) {
	}

	 /**
     * Returns a string representation of this map.  The string representation
     * consists of a list of key-value mappings in the order returned by the
     * map's entrySet view's iterator, enclosed in braces
     * ("{}").  Adjacent mappings are separated by the characters
     * ", " (comma and space).  Each key-value mapping is rendered as
     * the key followed by an equals sign ("=") followed by the
     * associated value.  Keys and values are converted to strings as by
     * {@link String#valueOf(Object)}.
     *
     * @return a string representation of this map
     */
    public String toString() {
       return ToStringFunctions.toString(this);
    }


	public IPersistentMap cons(Map.Entry o) {
		Pure4J.immutable(o);
		return assoc(o.getKey(), o.getValue());
	}

	public boolean equals(Object obj) {
		return mapEquals(this, obj);
	}

	@Pure
	static public  boolean mapEquals(IPersistentMap m1, Object obj) {
		Pure4J.immutable(m1, obj);
		if (m1 == obj)
			return true;
		if (!(obj instanceof Map))
			return false;
		
		Map m = (Map) obj;

		if (m.size() != m1.count())
			return false;
		
		for (ISeq> s = m1.seq(); s != null; s = s.next()) {
			Entry e = s.first();
			boolean found = m.containsKey(e.getKey());

			if (!found || !Util.equals(e.getValue(), m.get(e.getKey())))
				return false;
		}

		return true;
	}

	public int hashCode() {
		if (_hasheq == -1) {
			_hasheq = Hasher.hashUnordered(this);
		}
		return _hasheq;
	}

	static public int mapHasheq(IPersistentMap m) {
		return Hasher.hashUnordered(m);
	}

	static public class KeySeq extends ASeq {
		private static final long serialVersionUID = 5550732202968416322L;
		
		final ISeq> seq;

		@IgnoreImmutableTypeCheck
		final Iterable> iterable;

		@Pure
		static public  KeySeq create(ISeq> seq) {
			if (seq == null)
				return null;
			return new KeySeq(seq, null);
		}

		@Pure
		static public  KeySeq createFromMap(IPersistentMap map) {
			if (map == null)
				return null;
			ISeq> seq = map.seq();
			if (seq == null)
				return null;
			return new KeySeq(seq, map);
		}

		@Pure(Enforcement.FORCE)
		private KeySeq(ISeq> seq, Iterable> iterable) {
			this.seq = seq;
			this.iterable = iterable;
		}

		public K first() {
			return seq.first().getKey();
		}

		public ISeq next() {
			return create(seq.next());
		}

		@SuppressWarnings("unchecked")
		public IPureIterator iterator() {
			if (iterable == null)
				return super.iterator();

			if (iterable instanceof IMapIterable)
				return (IPureIterator) ((IMapIterable) iterable).keyIterator();

			final Iterator> mapIter = iterable.iterator();
			
			return new IPureIterator() {
				public boolean hasNext() {
					return mapIter.hasNext();
				}

				public K next() {
					return mapIter.next().getKey();
				}

				public void remove() {
					throw new UnsupportedOperationException();
				}
			};
		}
	}

	static public class ValSeq extends ASeq {
		
		final ISeq> seq;
		
		@IgnoreImmutableTypeCheck
		final Iterable> iterable;

		@Pure
		static public  ValSeq create(ISeq> seq) {
			if (seq == null)
				return null;
			return new ValSeq(seq, null);
		}

		@Pure
		static public  ValSeq createFromMap(IPersistentMap map) {
			if (map == null)
				return null;
			ISeq> seq = map.seq();
			if (seq == null)
				return null;
			return new ValSeq(seq, map);
		}
		
		@Pure(Enforcement.FORCE)
		private ValSeq(ISeq> seq, Iterable> iterable) {
			this.seq = seq;
			this.iterable = iterable;
		}

		public V first() {
			return seq.first().getValue();
		}

		public ISeq next() {
			return create(seq.next());
		}
		
		@SuppressWarnings("unchecked")
		public IPureIterator iterator() {
			if (iterable == null)
				return super.iterator();

			if (iterable instanceof IMapIterable)
				return (IPureIterator) ((IMapIterable) iterable).valIterator();

			final Iterator> mapIter = iterable.iterator();
			return new IPureIterator() {
				public boolean hasNext() {
					return mapIter.hasNext();
				}

				public V next() {
					return mapIter.next().getValue();
				}

				public void remove() {
					throw new UnsupportedOperationException();
				}
			};
		}
	}

	// java.util.Map implementation

	public void clear() {
		throw new UnsupportedOperationException();
	}

	public boolean containsValue(Object value) {
		Pure4J.immutable(value);
		return values().contains(value);
	}
	
	public Set> entrySet() {
		return new AImmutableSet>() {
			
			public Iterator> iterator() {
				return APersistentMap.this.iterator();
			}

			public int size() {
				return count();
			}

			public int hashCode() {
				return APersistentMap.this.hashCode();
			}

			public boolean contains(Object o) {
				if (o instanceof Entry) {
					Entry e = (Entry) o;
					Entry found = entryAt(e.getKey());
					if (found != null
							&& Util.equals(found.getValue(), e.getValue()))
						return true;
				}
				return false;
			}
		};
	}

	public boolean isEmpty() {
		return count() == 0;
	}

	public Set keySet() {
		return new AImmutableSet() {

			public Iterator iterator() {
				final Iterator> mi = APersistentMap.this.iterator();

				return new IPureIterator() {

					public boolean hasNext() {
						return mi.hasNext();
					}

					public K next() {
						Entry e = mi.next();
						return e.getKey();
					}

					public void remove() {
						throw new UnsupportedOperationException();
					}
				};
			}

			public int size() {
				return count();
			}

			public boolean contains(Object o) {
				return APersistentMap.this.containsKey(o);
			}
		};
	}

	public V put(K key, V value) {
		Pure4J.immutable(key, value);
		throw new UnsupportedOperationException();
	}

	public void putAll(Map t) {
		Pure4J.immutable(t);
		throw new UnsupportedOperationException();
	}

	public V remove(Object key) {
		Pure4J.immutable(key);
		throw new UnsupportedOperationException();
	}

	public int size() {
		return count();
	}

	public Collection values() {
		return new AImmutableCollection() {

			public Iterator iterator() {
				final Iterator> mi = APersistentMap.this.iterator();

				return new IPureIterator() {

					public boolean hasNext() {
						return mi.hasNext();
					}

					public V next() {
						Entry e = mi.next();
						return e.getValue();
					}

					public void remove() {
						throw new UnsupportedOperationException();
					}
				};
			}

			public int size() {
				return count();
			}
		};
	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy