alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Scala example source code file (MapLike.scala)

This example Scala source code file (MapLike.scala) is included in the DevDaily.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Java - Scala tags/keywords

a, a, b, b, b1, b1, c, c, defaultmap, gentraversableonce, map, maplike, that, this

The Scala MapLike.scala source code

/*                     __                                               *\
**     ________ ___   / /  ___     Scala API                            **
**    / __/ __// _ | / /  / _ |    (c) 2003-2011, LAMP/EPFL             **
**  __\ \/ /__/ __ |/ /__/ __ |    http://scala-lang.org/               **
** /____/\___/_/ |_/____/_/ | |                                         **
**                          |/                                          **
\*                                                                      */

package scala.collection
package immutable

import generic._
import parallel.immutable.ParMap
import annotation.bridge

/** 
 *  A generic template for immutable maps from keys of type `A`
 *  to values of type `B`.
 *  To implement a concrete map, you need to provide implementations of the
 *  following methods (where `This` is the type of the actual map implementation):
 *  
 *  {{{
 *    def get(key: A): Option[B]
 *    def iterator: Iterator[(A, B)]
 *    def + [B1 >: B](kv: (A, B)): Map[A, B1]
 *    def - (key: A): This
 *  }}}
 *  
 *  If you wish that transformer methods like `take`, `drop`, `filter` return the 
 *  same kind of map, you should also override:
 *  
 *  {{{
 *    def empty: This
 *  }}}
 *  
 *  It is also good idea to override methods `foreach` and
 *  `size` for efficiency.
 *  
 *  @param A     the type of the keys contained in this collection.
 *  @param B     the type of the values associated with the keys.
 *  @param This  The type of the actual map implementation.
 *  
 *  @author  Martin Odersky
 *  @version 2.8
 *  @since   2.8
 *  @define Coll immutable.Map
 *  @define coll immutable map
 */
trait MapLike[A, +B, +This <: MapLike[A, B, This] with Map[A, B]]
  extends scala.collection.MapLike[A, B, This]
     with Parallelizable[(A, B), ParMap[A, B]]
{ self =>

  protected[this] override def parCombiner = ParMap.newCombiner[A, B]

  /** A new immutable map containing updating this map with a given key/value mapping. 
   *  @param    key the key
   *  @param    value the value
   *  @return   A new map with the new key/value mapping 
   */
  override def updated [B1 >: B](key: A, value: B1): immutable.Map[A, B1] = this + ((key, value))

  /** Add a key/value pair to this map, returning a new map. 
   *  @param    kv the key/value pair.
   *  @return   A new map with the new binding added to this map.
   */
  def + [B1 >: B] (kv: (A, B1)): immutable.Map[A, B1]

  /** Adds two or more elements to this collection and returns
   *  a new collection.
   *
   *  @param elem1 the first element to add.
   *  @param elem2 the second element to add.
   *  @param elems the remaining elements to add.
   *  @return A new map with the new bindings added to this map.
   */
  override def + [B1 >: B] (elem1: (A, B1), elem2: (A, B1), elems: (A, B1) *): immutable.Map[A, B1] =
    this + elem1 + elem2 ++ elems

  /** Adds a number of elements provided by a traversable object
   *  and returns a new collection with the added elements.
   *
   *  @param xs      the traversable object consisting of key-value pairs.
   *  @return        a new immutable map with the bindings of this map and those from `xs`.
   */
  override def ++[B1 >: B](xs: GenTraversableOnce[(A, B1)]): immutable.Map[A, B1] = 
    ((repr: immutable.Map[A, B1]) /: xs.seq) (_ + _)

  @bridge def ++[B1 >: B](xs: TraversableOnce[(A, B1)]): immutable.Map[A, B1] = ++(xs: GenTraversableOnce[(A, B1)])

  /** Filters this map by retaining only keys satisfying a predicate.
   *  @param  p   the predicate used to test keys
   *  @return an immutable map consisting only of those key value pairs of this map where the key satisfies
   *          the predicate `p`. The resulting map wraps the original map without copying any elements.
   */
  override def filterKeys(p: A => Boolean): Map[A, B] = new DefaultMap[A, B] {
    override def foreach[C](f: ((A, B)) => C): Unit = for (kv <- self) if (p(kv._1)) f(kv)
    def iterator = self.iterator.filter(kv => p(kv._1))
    override def contains(key: A) = self.contains(key) && p(key)
    def get(key: A) = if (!p(key)) None else self.get(key)
  }    

  /** Transforms this map by applying a function to every retrieved value.
   *  @param  f   the function used to transform values of this map.
   *  @return a map view which maps every key of this map
   *          to `f(this(key))`. The resulting map wraps the original map without copying any elements.
   */
  override def mapValues[C](f: B => C): Map[A, C] = new DefaultMap[A, C] {
    override def foreach[D](g: ((A, C)) => D): Unit = for ((k, v) <- self) g((k, f(v)))
    def iterator = for ((k, v) <- self.iterator) yield (k, f(v))
    override def size = self.size
    override def contains(key: A) = self.contains(key)
    def get(key: A) = self.get(key).map(f)
  }
  
  /** Collects all keys of this map in a set.
   *  @return  a set containing all keys of this map.
   */
  override def keySet: immutable.Set[A] = new ImmutableDefaultKeySet
  
  protected class ImmutableDefaultKeySet extends super.DefaultKeySet with immutable.Set[A] {
    override def + (elem: A): immutable.Set[A] =
      if (this(elem)) this
      else immutable.Set[A]() ++ this + elem
    override def - (elem: A): immutable.Set[A] = 
      if (this(elem)) immutable.Set[A]() ++ this - elem
      else this
  }

  /** This function transforms all the values of mappings contained
   *  in this map with function `f`.
   *
   *  @param f A function over keys and values
   *  @return  the updated map
   */
  def transform[C, That](f: (A, B) => C)(implicit bf: CanBuildFrom[This, (A, C), That]): That = {
    val b = bf(repr)
    for ((key, value) <- this) b += ((key, f(key, value)))
    b.result
  }
}

Other Scala examples (source code examples)

Here is a short list of links related to this Scala MapLike.scala source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.