hashset.scala

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

SCALA
137
字号
/*                     __                                               *\**     ________ ___   / /  ___     Scala API                            ****    / __/ __// _ | / /  / _ |    (c) 2003-2008, LAMP/EPFL             ****  __\ \/ /__/ __ |/ /__/ __ |    http://scala-lang.org/               **** /____/\___/_/ |_/____/_/ | |                                         ****                          |/                                          **\*                                                                      */// $Id: HashSet.scala 14726 2008-04-21 10:14:06Z odersky $package scala.collection.immutable/** The canonical factory methods for <a href="HashSet.html">immutable HashSet's<la>.  *  *  @author  Martin Odersky  *  @version 2.0, 19/01/2007  */object HashSet {  /** The empty set of this type.   */  def empty[A] = new HashSet[A]  /** The canonical factory for this type   */  def apply[A](elems: A*) = empty[A] ++ elems}/** This class implements immutable maps/sets using a hash table.  * It is optimized for sequential accesses where the last updated table is accessed most often.  * It supports with reasonable efficiency accesses to previous versions of the table by keeping  * a change log that's regularly compacted.  * It needs to synchronize most methods, so it is less suitable for highly concurrent accesses.  *  *  @author  Martin Odersky  *  @version 2.0, 19/01/2007  */@serializableclass HashSet[A] extends Set[A] with mutable.FlatHashTable[A] {  protected var later: HashSet[A] = null  protected var changedElem: A = _  protected var deleted: Boolean = _  def empty[C]: Set[C] = new EmptySet[C]  def contains(elem: A): Boolean = synchronized {    var m = this    var cnt = 0    while (m.later != null) {      if (elem == m.changedElem) return m.deleted      cnt += 1      m = m.later    }    if (cnt > logLimit) makeCopy(m)    m.containsEntry(elem)  }  def + (elem: A): Set[A] = synchronized {    makeCopyIfUpdated()    if (containsEntry(elem)) this    else {      markUpdated(elem, false)      later addEntry elem      later    }  }  def - (elem: A): Set[A] = synchronized {    makeCopyIfUpdated()    if (!containsEntry(elem)) this    else {      markUpdated(elem, true)      later removeEntry elem      later    }  }  override def size: Int = synchronized {    var m = this    var cnt = 0    var s = 0    while (m.later != null) {      if (m.deleted) s += 1 else s -= 1      cnt += 1      m = m.later    }    s += m.tableSize    if (cnt > logLimit) makeCopy(m)      s  }  override def elements = synchronized {    makeCopyIfUpdated()    // note need to cache because (later versions of) set might be mutated while elements are traversed.    val cached = new mutable.ArrayBuffer() ++ super.elements    cached.elements  }  private def logLimit: Int = Math.sqrt(table.length).toInt  private def markUpdated(elem: A, del: Boolean) {     val lv = loadFactor    later = new HashSet[A] {      override def initialSize = 0      override def loadFactor = lv      table     = HashSet.this.table      tableSize = HashSet.this.tableSize      threshold = HashSet.this.threshold    }    changedElem = elem    deleted = del  }  private def makeCopy(last: HashSet[A]) {    def undo(m: HashSet[A]) {      if (m ne last) {        undo(m.later)        if (m.deleted) addEntry(m.changedElem)        else removeEntry(m.changedElem)      }    }    table = new Array[AnyRef](last.table.length)    Array.copy(last.table, 0, table, 0, table.length)    tableSize = last.tableSize    threshold = last.threshold    undo(this)    later = null  }  private def makeCopyIfUpdated() {    var m = this    while (m.later != null) m = m.later    if (m ne this) makeCopy(m)  }}

⌨️ 快捷键说明

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