summaryrefslogtreecommitdiff
path: root/src/library/scala/collection/mutable/MapLike.scala
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2009-09-25 16:20:13 +0000
committerMartin Odersky <odersky@gmail.com>2009-09-25 16:20:13 +0000
commit4a727f3b01d0fa27ef51f7dba472116e021e3445 (patch)
treec9ab55ea7fe6051455271b23e9fbfc2f313015c0 /src/library/scala/collection/mutable/MapLike.scala
parente31f18094dfba97c80871869a037172ff2c9c1c2 (diff)
downloadscala-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.scala271
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
+ }
+}