diff options
author | Martin Odersky <odersky@gmail.com> | 2009-09-25 16:20:13 +0000 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2009-09-25 16:20:13 +0000 |
commit | 4a727f3b01d0fa27ef51f7dba472116e021e3445 (patch) | |
tree | c9ab55ea7fe6051455271b23e9fbfc2f313015c0 /src/library/scala/collection/mutable/MapLike.scala | |
parent | e31f18094dfba97c80871869a037172ff2c9c1c2 (diff) | |
download | scala-4a727f3b01d0fa27ef51f7dba472116e021e3445.tar.gz scala-4a727f3b01d0fa27ef51f7dba472116e021e3445.tar.bz2 scala-4a727f3b01d0fa27ef51f7dba472116e021e3445.zip |
Collections refactoring.
Diffstat (limited to 'src/library/scala/collection/mutable/MapLike.scala')
-rw-r--r-- | src/library/scala/collection/mutable/MapLike.scala | 271 |
1 files changed, 271 insertions, 0 deletions
diff --git a/src/library/scala/collection/mutable/MapLike.scala b/src/library/scala/collection/mutable/MapLike.scala new file mode 100644 index 0000000000..3e72d23ba3 --- /dev/null +++ b/src/library/scala/collection/mutable/MapLike.scala @@ -0,0 +1,271 @@ +/* __ *\ +** ________ ___ / / ___ Scala API ** +** / __/ __// _ | / / / _ | (c) 2003-2009, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** +** /____/\___/_/ |_/____/_/ | | ** +** |/ ** +\* */ + +// $Id$ + + +package scala.collection +package mutable + +import generic._ + +/** <p> + * A generic template for mutable maps from keys of type <code>A</code> to + * values of type <code>B</code>. + * </p> + * <p> + * To implement a concrete mutable map, you need to provide implementations + * of the following methods: + * </p><pre> + * <b>def</b> get(key: A): Option[B] + * <b>def</b> iterator: Iterator[(A, B)] + * <b>def</b> += (kv: (A, B)): <b>this.type</b> + * <b>def</b> -= (key: A): <b>this.type</b></pre> + * <p> + * If you wish that methods <code>like</code>, <code>take</code>, + * <code>drop</code>, <code>filter</code> return the same kind of map, you + * should also override: + * </p><pre> + * <b>def</b> empty: This</pre> + * <p> + * If you to avoid the unncessary construction of an <code>Option</code> + * object, you could also override <code>apply</code>, <code>update</code>, + * and <code>delete</code>. + * </p> + * <p> + * It is also good idea to override methods <code>foreach</code> and + * <code>size</code> for efficiency. + * </p> + */ +trait MapLike[A, B, +This <: MapLike[A, B, This] with Map[A, B]] + extends MapLikeBase[A, B, This] + with Builder[(A, B), This] + with Growable[(A, B)] + with Shrinkable[A] + with Cloneable[This] +{ self => + + import scala.collection.Traversable + + /** <p> + * A common implementation of <code>newBuilder</code> for all mutable maps + * in terms of <code>empty</code>. + * </p> + * <p> + * Overrides <code>MapLike</code> implementation for better efficiency. + * </p> + */ + override protected[this] def newBuilder: Builder[(A, B), This] = empty + + /** Adds a new mapping from <code>key</code> + * to <code>value</code> to the map. If the map already contains a + * mapping for <code>key</code>, it will be overridden. + * + * @param key The key to update + * @param value The new value + */ + def put(key: A, value: B): Option[B] = { + val r = get(key) + update(key, value) + r + } + + /** Adds a new mapping from <code>key</code> + * to <code>value</code> to the map. If the map already contains a + * mapping for <code>key</code>, it will be overridden. + * + * @param key The key to update + * @param value The new value + * @return An option consisting of value associated previously associated with `key` in the map, + * or None if `key` was not yet defined in the map. + */ + def update(key: A, value: B) { this += ((key, value)) } + + /** Add a new key/value mapping this map. + * @param kv the key/value pair. + * @return the map itself + */ + def += (kv: (A, B)): this.type + + /** Create a new map consisting of all elements of the current map + * plus the given mapping from <code>key</code> to <code>value</code>. + * + * @param key The key to ad + * @param value The new value + * @return A fresh immutable map + */ + override def updated[B1 >: B](key: A, value: B1): mutable.Map[A, B1] = this + ((key, value)) + + /** If given key is already in this map, returns associated value + * Otherwise, computes value from given expression `op`, stores with key + * in map and returns that value. + */ + def cached(key: A, op: => B) = get(key) match { + case Some(v) => v + case None => val v = op; update(key, v); v + } + + /** Add a new key/value mapping and return the map itself. + * + * @param kv the key/value mapping to be added + */ + @deprecated("This operation will create a new map in the future. To add an element as a side\n"+ + "effect to an existing map and return that map itself, use +=. If you do want\n"+ + "to create a fresh map, you can use `clone() +=' to avoid a @deprecated warning.") + def + (kv: (A, B)): this.type = { update(kv._1, kv._2); this } + + /** Adds two or more key/value mappings and return the map itself. + * with the added elements. + * + * @param elem1 the first element to add. + * @param elem2 the second element to add. + * @param elems the remaining elements to add. + */ + @deprecated("This operation will create a new map in the future. To add an element as a side\n"+ + "effect to an existing map and return that map itself, use +=. If you do want to\n"+ + "create a fresh map, you can use `clone() +=` to avoid a @deprecated warning.") + def +(elem1: (A, B), elem2: (A, B), elems: (A, B)*): this.type = + this += elem1 += elem2 ++= elems + + /** Adds a number of elements provided by a traversable object + * via its <code>iterator</code> method and returns + * either the collection itself (if it is mutable), or a new collection + * with the added elements. + * + * @param iter the traversable object. + */ + @deprecated("This operation will create a new map in the future. To add elements as a side\n"+ + "effect to an existing map and return that map itself, use ++=. If you do want\n"+ + "to create a fresh map, you can use `clone() ++=` to avoid a @deprecated warning.") + def ++(iter: Traversable[(A, B)]): this.type = { for (elem <- iter) +=(elem); this } + + /** Adds a number of elements provided by an iterator + * via its <code>iterator</code> method and returns + * the collection itself. + * + * @param iter the iterator + */ + @deprecated("This operation will create a new map in the future. To add elements as a side\n"+ + "effect to an existing map and return that map itself, use ++=. If you do want\n"+ + "to create a fresh map, you can use `clone() +=` to avoid a @deprecated warning.") + def ++(iter: Iterator[(A, B)]): this.type = { for (elem <- iter) +=(elem); this } + + /** If given key is defined in this map, remove it and return associated value as an Option. + * If key is not present return None. + * @param key the key to be removed + */ + def remove(key: A): Option[B] = { + val r = get(key) + this -= key + r + } + + /** Delete a key from this map if it is present. + * @param key the key to be removed + * @note same as `delete`. + */ + def -= (key: A): this.type + + /** Delete a key from this map if it is present and return the map itself. + * @param key the key to be removed + */ + @deprecated("This operation will create a new map in the future. To add elements as a side\n"+ + "effect to an existing map and return that map itself, use -=. If you do want\n"+ + "to create a fresh map, you can use `clone() -=` to avoid a @deprecated warning.") + override def -(key: A): This = { -=(key); repr } + + /** If given key is defined in this map, remove it and return associated value as an Option. + * If key is not present return None. + * @param key the key to be removed + */ + @deprecated("Use `remove' instead") def removeKey(key: A): Option[B] = remove(key) + + + /** Removes all elements from the set. After this operation is completed, + * the set will be empty. + */ + def clear() { for ((k, v) <- this.iterator) -=(k) } + + /** Check if this map maps <code>key</code> to a value. + * Return that value if it exists, otherwise put <code>default</code> + * as that key's value and return it. + */ + def getOrElseUpdate(key: A, default: => B): B = + get(key) match { + case Some(v) => v + case None => val d = default; this(key) = d; d + } + + /** This function transforms all the values of mappings contained + * in this map with function <code>f</code>. + * + * @param f The transformation to apply + */ + def transform(f: (A, B) => B): this.type = { + this.iterator foreach { + case (key, value) => update(key, f(key, value)) + } + this + } + + /** Retain only those mappings for which the predicate + * <code>p</code> returns <code>true</code>. + * + * @param p The test predicate + */ + @deprecated("cannot be type inferred because of retain in Iterable.") + def retain(p: (A, B) => Boolean): this.type = { + for ((k, v) <- this) if (!p(k, v)) -=(k) + this + } + + override def clone(): This = + empty ++= repr + + /** The result when this map is used as a builder */ + def result: This = repr + + /** Removes two or more elements from this collection and returns + * the collection itself. + * + * @param elem1 the first element to remove. + * @param elem2 the second element to remove. + * @param elems the remaining elements to remove. + */ + @deprecated("Use -= instead if you intend to remove by side effect from an existing collection.\n"+ + "Use `clone() -=' if you intend to create a new collection.") + override def -(elem1: A, elem2: A, elems: A*): This = { + this -= elem1 -= elem2 --= elems + repr + } + + /** Removes a number of elements provided by a Traversable object and returns + * the collection itself. + * + * @param iter the Traversable object. + */ + @deprecated("Use --= instead if you intend to remove by side effect from an existing collection.\n"+ + "Use `clone() --=' if you intend to create a new collection.") + override def --(iter: Traversable[A]): This = { + for (elem <- iter) -=(elem) + repr + } + + + /** Removes a number of elements provided by an iterator and returns + * the collection itself. + * + * @param iter the iterator + */ + @deprecated("Use --= instead if you intend to remove by side effect from an existing collection.\n"+ + "Use `clone() --=' if you intend to create a new collection.") + override def --(iter: Iterator[A]): This = { + for (elem <- iter) -=(elem) + repr + } +} |