map.scala

来自「JAVA 语言的函数式编程扩展」· SCALA 代码 · 共 199 行

SCALA
199
字号
/*                     __                                               *\**     ________ ___   / /  ___     Scala API                            ****    / __/ __// _ | / /  / _ |    (c) 2003-2008, LAMP/EPFL             ****  __\ \/ /__/ __ |/ /__/ __ |    http://scala-lang.org/               **** /____/\___/_/ |_/____/_/ | |                                         ****                          |/                                          **\*                                                                      */// $Id: Map.scala 13737 2008-01-18 19:15:23Z michelou $package scala.collectionimport Predef._object Map {  trait Projection[A, +B] extends Iterable.Projection[(A, B)] with Map[A, B]}/** <p>*     A map is a collection that maps each key to one or zero values. *  </p> *  <p> *    This trait provides a limited interface, only allowing reading of elements. *    There are two extensions of this trait, in packages *    <code><a href="mutable$content.html" target="contentFrame"> *    scala.collection.mutable</a></code> *    and <code><a href="immutable$content.html" target="contentFrame"> *    scala.collection.immutable</a></code>, which provide functionality for *    adding new key/value mappings to a map. The trait in the first package is *    for maps that are modified destructively, whereas the trait in *    the second package is for immutable maps which create a new map *    when something is added or removed from them. *  </p> * *  @author  Matthias Zenger *  @author  Martin Odersky *  @version 1.2, 31/12/2006 */trait Map[A, +B] extends PartialFunction[A, B] with Collection[(A, B)] {  /** Compute the number of key-to-value mappings.   *   *  @return the number of mappings   */  def size: Int  /** Check if this map maps <code>key</code> to a value and return the   *  value if it exists.   *   *  @param  key the key of the mapping of interest   *  @return     the value of the mapping, if it exists   */  def get(key: A): Option[B]      /** Check if this map maps <code>key</code> to a value.    *  Return that value if it exists, otherwise return <code>default</code>.    */  def getOrElse[B2 >: B](key: A, default: => B2): B2 =    get(key) match {      case Some(v) => v      case None => default     }  /** Is this an empty map?   *   *  @return <code>true</code> iff the map is empty.   */  override def isEmpty: Boolean = size == 0  /** Retrieve the value which is associated with the given key. This   *  method throws an exception if there is no mapping from the given   *  key to a value.   *   *  @param  key the key   *  @return     the value associated with the given key.   */  def apply(key: A): B = get(key) match {    case None => default(key)    case Some(value) => value  }  /** Is the given key mapped to a value by this map?   *   *  @param key the key   *  @return    <code>true</code> iff there is a mapping for key in this map   */  def contains(key: A): Boolean = get(key) match {    case None => false    case Some(_) => true  }  /** Does this map contain a mapping from the given key to a value?   *   *  @param key the key   *  @return    <code>true</code> iff there is a mapping for key in this map   */  def isDefinedAt(key: A) = contains(key)  /** Creates an iterator for all keys.   *   *  @return an iterator over all keys.   */  def keys: Iterator[A] = new Iterator[A] {    val iter = Map.this.elements    def hasNext = iter.hasNext    def next = iter.next._1  }  /** @return the keys of this map as a set.    */  def keySet: Set[A] = new Set[A] {    def size = Map.this.size    def contains(key : A) = Map.this.contains(key)    def elements = Map.this.elements.map(_._1)  }  /** Creates an iterator for a contained values.   *   *  @return an iterator over all values.   */  def values: Iterator[B] = new Iterator[B] {    val iter = Map.this.elements    def hasNext = iter.hasNext    def next = iter.next._2  }  /** Compares two maps structurally; i.e. checks if all mappings   *  contained in this map are also contained in the other map,   *  and vice versa.   *   *  @param that the other map   *  @return     <code>true</code> iff both maps contain exactly the   *              same mappings.   */  override def equals(that: Any): Boolean = that match {    case other: Map[a, b] =>      this.size == other.size && this.elements.forall {        case (key, value) => other.get(key.asInstanceOf[a]) match {          case None => false          case Some(otherval) => value == otherval        }      }    case _ => false  }  /** A hash method compatible with <code>equals</code>    */  override def hashCode() =    (0 /: elements) ((hash, kv) => hash + kv.hashCode)  /** Creates a string representation for this map.   *   *  @return    a string showing all mappings   */  override def toString() =    elements.toList.map(kv => kv._1 + " -> " + kv._2).mkString("Map(", ", ", ")")      /** The default value for the map, returned when a key is not found   *  The method implemented here yields an error,   *  but it might be overridden in subclasses.   *   *  @param key the given key value   *  @throws Predef.NoSuchElementException   */  def default(key: A): B =    throw new NoSuchElementException("key not found: " + key)      override def projection: Map.Projection[A,B] = new Map.Projection[A, B] {    override def elements = Map.this.elements    override def size = Map.this.size    override def get(key: A): Option[B] = Map.this.get(key)  }  /** non-strict filter based on keys only */  def filterKeys(p: A => Boolean): Map.Projection[A, B] = new Map.Projection[A, B] {    def elements = Map.this.elements.filter(x => p(x._1))    def size = {      var sz = 0      Map.this.foreach(x => if (p(x._1)) sz = sz + 1)      sz    }    override def contains(key: A) = Map.this.contains(key) && p(key)    override def get(key: A) = if (!p(key)) None else Map.this.get(key)  }  /** non-strict map elements using existing key set */  def mapElements[C](f: B => C) : Map.Projection[A,C] = new Map.Projection[A,C] {    def elements = Map.this.elements.map(e => (e._1, f(e._2)))    def size = Map.this.size    override def contains(key: A) = Map.this.contains(key)    override def get(key: A) = Map.this.get(key).map(f)  }  /** Defines the prefix of this object's <code>toString</code> representation.   */  override protected def stringPrefix: String = "Map"}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?