removed leading/trailing tabs/blanks in scala/List.scala
git-svn-id: http://lampsvn.epfl.ch/svn-repos/scala/scala/trunk@8662 5e8d7ff9-d8ef-0310-90f0-a4852d11357a
This commit is contained in:
parent
6d6a310d94
commit
dde538f7f0
|
@ -9,11 +9,11 @@
|
|||
// $Id$
|
||||
|
||||
|
||||
package scala;
|
||||
package scala
|
||||
|
||||
import scala.runtime.compat.StringBuilder
|
||||
import Predef._;
|
||||
import scala.collection.mutable.ListBuffer;
|
||||
import scala.collection.mutable.ListBuffer
|
||||
import Predef._
|
||||
|
||||
/** This object provides methods for creating specialized lists, and for
|
||||
* transforming special kinds of lists (e.g. lists of lists).
|
||||
|
@ -28,7 +28,7 @@ object List {
|
|||
* @param xs the elements to put in the list
|
||||
* @return the list containing elements xs.
|
||||
*/
|
||||
def apply[A](xs: A*): List[A] = xs.toList;
|
||||
def apply[A](xs: A*): List[A] = xs.toList
|
||||
|
||||
/** Create a sorted list of all integers in a range.
|
||||
*
|
||||
|
@ -37,19 +37,19 @@ object List {
|
|||
* @return the sorted list of all integers in range [from;end).
|
||||
*/
|
||||
def range(from: Int, end: Int): List[Int] =
|
||||
range(from, end, 1);
|
||||
range(from, end, 1)
|
||||
|
||||
/** Create a sorted list of all integers in a range.
|
||||
*
|
||||
* @param from the start value of the list
|
||||
* @param end the end value of the list
|
||||
* @param end the end value of the list
|
||||
* @param step the increment value of the list
|
||||
* @return the sorted list of all integers in range [from;end).
|
||||
* @return the sorted list of all integers in range [from;end).
|
||||
*/
|
||||
def range(from: Int, end: Int, step: Int): List[Int] = {
|
||||
val b = new ListBuffer[Int]
|
||||
var i = from
|
||||
while (i < end) {
|
||||
while (i < end) {
|
||||
b += i
|
||||
i = i + step
|
||||
}
|
||||
|
@ -59,14 +59,14 @@ object List {
|
|||
/** Create a sorted list of all integers in a range.
|
||||
*
|
||||
* @param from the start value of the list
|
||||
* @param end the end value of the list
|
||||
* @param end the end value of the list
|
||||
* @param step the increment function of the list
|
||||
* @return the sorted list of all integers in range [from;end).
|
||||
* @return the sorted list of all integers in range [from;end).
|
||||
*/
|
||||
def range(from: Int, end: Int, step: Int => Int): List[Int] = {
|
||||
val b = new ListBuffer[Int]
|
||||
var i = from
|
||||
while (i < end) {
|
||||
while (i < end) {
|
||||
b += i
|
||||
i = i + step(i)
|
||||
}
|
||||
|
@ -75,9 +75,9 @@ object List {
|
|||
|
||||
/** Create a list containing several copies of an element.
|
||||
*
|
||||
* @param n the length of the resulting list
|
||||
* @param n the length of the resulting list
|
||||
* @param elem the element composing the resulting list
|
||||
* @return a list composed of n elements all equal to elem
|
||||
* @return a list composed of n elements all equal to elem
|
||||
*/
|
||||
def make[a](n: Int, elem: a): List[a] = {
|
||||
val b = new ListBuffer[a]
|
||||
|
@ -108,12 +108,14 @@ object List {
|
|||
}
|
||||
|
||||
/** Concatenate all the elements of a given list of lists.
|
||||
*
|
||||
* @param xss the list of lists that are to be concatenated
|
||||
* @return the concatenation of all the lists
|
||||
* @return the concatenation of all the lists
|
||||
*/
|
||||
def flatten[a](xss: List[List[a]]): List[a] = concat(xss: _*)
|
||||
|
||||
/** Concatenate all the argument lists into a single list.
|
||||
*
|
||||
* @param xss the lists that are to be concatenated
|
||||
* @return the concatenation of all the lists
|
||||
*/
|
||||
|
@ -127,7 +129,7 @@ object List {
|
|||
}
|
||||
}
|
||||
b.toList
|
||||
}
|
||||
}
|
||||
|
||||
/** Transforms a list of pair into a pair of lists.
|
||||
*
|
||||
|
@ -149,51 +151,51 @@ object List {
|
|||
/** Converts an iterator to a list
|
||||
*
|
||||
* @param it the iterator to convert
|
||||
* @return a list that contains the elements returned by successive
|
||||
* calls to <code>it.next</code>
|
||||
* @return a list that contains the elements returned by successive
|
||||
* calls to <code>it.next</code>
|
||||
*/
|
||||
def fromIterator[a](it: Iterator[a]): List[a] = it.toList;
|
||||
|
||||
/** Converts an array into a list.
|
||||
*
|
||||
* @param arr the array to convert
|
||||
* @return a list that contains the same elements than <code>arr</code>
|
||||
* in the same order
|
||||
* @return a list that contains the same elements than <code>arr</code>
|
||||
* in the same order
|
||||
*/
|
||||
def fromArray[a](arr: Array[a]): List[a] = fromArray(arr, 0, arr.length);
|
||||
|
||||
/** Converts a range of an array into a list.
|
||||
*
|
||||
* @param arr the array to convert
|
||||
* @param arr the array to convert
|
||||
* @param start the first index to consider
|
||||
* @param len the lenght of the range to convert
|
||||
* @return a list that contains the same elements than <code>arr</code>
|
||||
* in the same order
|
||||
* @param len the lenght of the range to convert
|
||||
* @return a list that contains the same elements than <code>arr</code>
|
||||
* in the same order
|
||||
*/
|
||||
def fromArray[a](arr: Array[a], start: Int, len: Int): List[a] = {
|
||||
var res: List[a] = Nil;
|
||||
var i = start + len;
|
||||
var res: List[a] = Nil
|
||||
var i = start + len
|
||||
while (i > start) {
|
||||
i = i - 1;
|
||||
res = arr(i) :: res;
|
||||
i = i - 1
|
||||
res = arr(i) :: res
|
||||
}
|
||||
res
|
||||
}
|
||||
|
||||
/** Parses a string which contains substrings separated by a
|
||||
*
|
||||
* separator character and returns a list of all substrings.
|
||||
* @param str the string to parse
|
||||
*
|
||||
* @param str the string to parse
|
||||
* @param separator the separator character
|
||||
* @return the list of substrings
|
||||
* @return the list of substrings
|
||||
*/
|
||||
def fromString(str: String, separator: Char): List[String] = {
|
||||
var words: List[String] = List();
|
||||
var pos = str.length();
|
||||
var words: List[String] = List()
|
||||
var pos = str.length()
|
||||
while (pos > 0) {
|
||||
val pos1 = str.lastIndexOf(separator, pos - 1);
|
||||
val pos1 = str.lastIndexOf(separator, pos - 1)
|
||||
if (pos1 + 1 < pos)
|
||||
words = str.substring(pos1 + 1, pos) :: words;
|
||||
words = str.substring(pos1 + 1, pos) :: words
|
||||
pos = pos1
|
||||
}
|
||||
words
|
||||
|
@ -205,7 +207,7 @@ object List {
|
|||
* @return the string as a list of characters.
|
||||
*/
|
||||
def fromString(str: String): List[Char] =
|
||||
Iterator.fromString(str).toList;
|
||||
Iterator.fromString(str).toList
|
||||
|
||||
/** Returns the given list of characters as a string.
|
||||
*
|
||||
|
@ -213,19 +215,24 @@ object List {
|
|||
* @return the list in form of a string.
|
||||
*/
|
||||
def toString(xs: List[Char]): String = {
|
||||
val sb = new StringBuilder();
|
||||
var xc = xs;
|
||||
val sb = new StringBuilder()
|
||||
var xc = xs
|
||||
while (!xc.isEmpty) {
|
||||
sb.append(xc.head);
|
||||
xc = xc.tail;
|
||||
sb.append(xc.head)
|
||||
xc = xc.tail
|
||||
}
|
||||
sb.toString()
|
||||
}
|
||||
|
||||
/** Like xs map f, but returns xs unchanged if function `f' maps all elements to themselves
|
||||
/** Like xs map f, but returns <code>xs</code> unchanged if function
|
||||
* <code>f</code> maps all elements to themselves.
|
||||
*
|
||||
* @param xs ...
|
||||
* @param f ...
|
||||
* @return ...
|
||||
*/
|
||||
def mapConserve[a <: AnyRef](xs: List[a])(f: a => a): List[a] = {
|
||||
def loop(ys: List[a]): List[a] =
|
||||
def loop(ys: List[a]): List[a] =
|
||||
if (ys.isEmpty) xs
|
||||
else {
|
||||
val head0 = ys.head
|
||||
|
@ -249,8 +256,8 @@ object List {
|
|||
loop(xs)
|
||||
}
|
||||
|
||||
/** Returns the list resulting from applying the given function <code>f</code> to
|
||||
* corresponding elements of the argument lists.
|
||||
/** Returns the list resulting from applying the given function <code>f</code>
|
||||
* to corresponding elements of the argument lists.
|
||||
*
|
||||
* @param f function to apply to each pair of elements.
|
||||
* @return <code>[f(a0,b0), ..., f(an,bn)]</code> if the lists are
|
||||
|
@ -273,7 +280,7 @@ object List {
|
|||
* corresponding elements of the argument lists.
|
||||
*
|
||||
* @param f function to apply to each pair of elements.
|
||||
* @return <code>[f(a0,b0,c0), ..., f(an,bn,cn)]</code> if the lists are
|
||||
* @return <code>[f(a0,b0,c0), ..., f(an,bn,cn)]</code> if the lists are
|
||||
* <code>[a0, ..., ak]</code>, <code>[b0, ..., bl]</code>, <code>[c0, ..., cm]</code> and
|
||||
* <code>n = min(k,l,m)</code>
|
||||
*/
|
||||
|
@ -295,9 +302,9 @@ object List {
|
|||
* for all corresponding elements of the argument lists.
|
||||
*
|
||||
* @param p function to apply to each pair of elements.
|
||||
* @return <code>n == 0 || (p(a0,b0) && ... && p(an,bn))]</code> if the lists are
|
||||
* <code>[a0, ..., ak]</code>, <code>[b0, ..., bl]</code> and
|
||||
* <code>m = min(k,l)</code>
|
||||
* @return <code>n == 0 || (p(a0,b0) && ... && p(an,bn))]</code>
|
||||
* if the lists are <code>[a0, ..., ak]</code>, <code>[b0, ..., bl]</code>
|
||||
* and <code>m = min(k,l)</code>
|
||||
*/
|
||||
def forall2[a,b](xs: List[a], ys: List[b])(f: (a, b) => boolean): boolean = {
|
||||
var xc = xs
|
||||
|
@ -310,11 +317,11 @@ object List {
|
|||
true
|
||||
}
|
||||
|
||||
/** Tests whether the given predicate <code>p</code> holds
|
||||
/** Tests whether the given predicate <code>p</code> holds
|
||||
* for some corresponding elements of the argument lists.
|
||||
*
|
||||
* @param p function to apply to each pair of elements.
|
||||
* @return <code>n != 0 && (p(a0,b0) || ... || p(an,bn))]</code> if the lists are
|
||||
* @return <code>n != 0 && (p(a0,b0) || ... || p(an,bn))]</code> if the lists are
|
||||
* <code>[a0, ..., ak]</code>, <code>[b0, ..., bl]</code> and
|
||||
* <code>m = min(k,l)</code>
|
||||
*/
|
||||
|
@ -332,9 +339,9 @@ object List {
|
|||
/** Transposes a list of lists.
|
||||
* pre: All element lists have the same length.
|
||||
*/
|
||||
def transpose[a](xss: List[List[a]]): List[List[a]] =
|
||||
def transpose[a](xss: List[List[a]]): List[List[a]] =
|
||||
if (xss.head.isEmpty) List()
|
||||
else (xss map (xs => xs.head)) :: transpose(xss map (xs => xs.tail));
|
||||
else (xss map (xs => xs.head)) :: transpose(xss map (xs => xs.tail))
|
||||
|
||||
/** Lists with ordered elements are ordered
|
||||
implicit def list2ordered[a <% Ordered[a]](x: List[a]): Ordered[List[a]] = new Ordered[List[a]] {
|
||||
|
@ -365,24 +372,24 @@ object List {
|
|||
* @author Martin Odersky and others
|
||||
* @version 1.0, 16/07/2003
|
||||
*/
|
||||
sealed abstract class List[+a] extends Seq[a] with CaseClass {
|
||||
sealed abstract class List[+a] extends Seq[a] with CaseClass {
|
||||
|
||||
/** Returns true if the list does not contain any elements.
|
||||
* @return true, iff the list is empty.
|
||||
*/
|
||||
override def isEmpty: Boolean;
|
||||
override def isEmpty: Boolean
|
||||
|
||||
/** Returns this first element of the list.
|
||||
* @return the first element of this list.
|
||||
* @throws <code>java.lang.RuntimeException</code> if the list is empty.
|
||||
*/
|
||||
def head: a;
|
||||
def head: a
|
||||
|
||||
/** Returns this list without its first element.
|
||||
* @return this list without its first element.
|
||||
* @throws <code>java.lang.RuntimeException</code> if the list is empty.
|
||||
*/
|
||||
def tail: List[a];
|
||||
def tail: List[a]
|
||||
|
||||
/** Add an element <code>x</code> at the beginning of this list.
|
||||
* <p/>
|
||||
|
@ -392,7 +399,7 @@ sealed abstract class List[+a] extends Seq[a] with CaseClass {
|
|||
* @return the list with <code>x</code> appended at the beginning.
|
||||
*/
|
||||
def ::[b >: a] (x: b): List[b] =
|
||||
new scala.::(x, this);
|
||||
new scala.::(x, this)
|
||||
|
||||
/** Returns a list resulting from the concatenation of the given
|
||||
* list <code>prefix</code> and this list.
|
||||
|
@ -402,7 +409,7 @@ sealed abstract class List[+a] extends Seq[a] with CaseClass {
|
|||
* @param prefix the list to concatenate at the beginning of this list.
|
||||
* @return the concatenation of the two lists.
|
||||
*/
|
||||
def :::[b >: a](prefix: List[b]): List[b] =
|
||||
def :::[b >: a](prefix: List[b]): List[b] =
|
||||
if (isEmpty) prefix
|
||||
else {
|
||||
val b = new ListBuffer[b]
|
||||
|
@ -431,10 +438,10 @@ sealed abstract class List[+a] extends Seq[a] with CaseClass {
|
|||
* @return the number of elements in the list.
|
||||
*/
|
||||
def length: Int = {
|
||||
var these = this;
|
||||
var len = 0;
|
||||
var these = this
|
||||
var len = 0
|
||||
while (!these.isEmpty) {
|
||||
len = len + 1;
|
||||
len = len + 1
|
||||
these = these.tail
|
||||
}
|
||||
len
|
||||
|
@ -462,22 +469,22 @@ sealed abstract class List[+a] extends Seq[a] with CaseClass {
|
|||
* @return an iterator on the list elements.
|
||||
*/
|
||||
def elements: Iterator[a] = new Iterator[a] {
|
||||
var these = List.this;
|
||||
def hasNext: Boolean = !these.isEmpty;
|
||||
var these = List.this
|
||||
def hasNext: Boolean = !these.isEmpty
|
||||
def next: a =
|
||||
if (!hasNext)
|
||||
error("next on empty Iterator")
|
||||
else {
|
||||
val result = these.head; these = these.tail; result
|
||||
}
|
||||
override def toList: List[a] = these;
|
||||
override def toList: List[a] = these
|
||||
}
|
||||
|
||||
/** Overrides the method in Iterable for efficiency.
|
||||
*
|
||||
* @return the list itself
|
||||
*/
|
||||
override def toList: List[a] = this;
|
||||
override def toList: List[a] = this
|
||||
|
||||
/** Returns the list without its last element.
|
||||
*
|
||||
|
@ -485,7 +492,7 @@ sealed abstract class List[+a] extends Seq[a] with CaseClass {
|
|||
* @throws <code>java.lang.RuntimeException</code> if the list is empty.
|
||||
*/
|
||||
def init: List[a] =
|
||||
if (isEmpty) error("Nil.init")
|
||||
if (isEmpty) error("Nil.init")
|
||||
else {
|
||||
val b = new ListBuffer[a]
|
||||
var elem = head
|
||||
|
@ -503,10 +510,10 @@ sealed abstract class List[+a] extends Seq[a] with CaseClass {
|
|||
* @return the last element of the list.
|
||||
* @throws <code>java.lang.RuntimeException</code> if the list is empty.
|
||||
*/
|
||||
def last: a =
|
||||
def last: a =
|
||||
if (isEmpty) error("Nil.last")
|
||||
else if (tail.isEmpty) head
|
||||
else tail.last;
|
||||
else tail.last
|
||||
|
||||
/** Returns the <code>n</code> first elements of this list.
|
||||
*
|
||||
|
@ -532,7 +539,7 @@ sealed abstract class List[+a] extends Seq[a] with CaseClass {
|
|||
*/
|
||||
override def drop(n: Int): List[a] =
|
||||
if (n == 0 || isEmpty) this
|
||||
else (tail drop (n-1));
|
||||
else (tail drop (n-1))
|
||||
|
||||
/** Returns the rightmost <code>n</code> elements from this list.
|
||||
*
|
||||
|
@ -572,7 +579,7 @@ sealed abstract class List[+a] extends Seq[a] with CaseClass {
|
|||
def splitAt(n: Int): Pair[List[a], List[a]] = {
|
||||
val b = new ListBuffer[a]
|
||||
var i = 0
|
||||
var these = this;
|
||||
var these = this
|
||||
while (!these.isEmpty && i < n) {
|
||||
i = i + 1
|
||||
b += these.head
|
||||
|
@ -637,7 +644,7 @@ sealed abstract class List[+a] extends Seq[a] with CaseClass {
|
|||
* @return the element at position <code>n</code> in this list.
|
||||
* @throws <code>java.lang.RuntimeException</code> if the list is too short.
|
||||
*/
|
||||
def apply(n: Int): a = drop(n).head;
|
||||
def apply(n: Int): a = drop(n).head
|
||||
|
||||
/** Returns the list resulting from applying the given function <code>f</code> to each
|
||||
* element of this list.
|
||||
|
@ -676,12 +683,12 @@ sealed abstract class List[+a] extends Seq[a] with CaseClass {
|
|||
* @param f the treatment to apply to each element.
|
||||
*/
|
||||
override def foreach(f: a => Unit): Unit = {
|
||||
var these = this;
|
||||
var these = this
|
||||
while (!these.isEmpty) {
|
||||
f(these.head)
|
||||
these = these.tail
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Returns all the elements of this list that satisfy the
|
||||
* predicate <code>p</code>. The order of the elements is preserved.
|
||||
|
@ -718,7 +725,7 @@ sealed abstract class List[+a] extends Seq[a] with CaseClass {
|
|||
* @param p the predicate to use to test elements
|
||||
* @return the list without all elements which satisfy <code>p</code>
|
||||
*/
|
||||
def remove(p: a => Boolean): List[a] = filter (x => !p(x));
|
||||
def remove(p: a => Boolean): List[a] = filter (x => !p(x))
|
||||
|
||||
/** Partition the list in two sub-lists according to a predicate.
|
||||
*
|
||||
|
@ -767,8 +774,8 @@ sealed abstract class List[+a] extends Seq[a] with CaseClass {
|
|||
else if (lt(z, y)) z::y::x::acc
|
||||
else y::z::x::acc
|
||||
case hd1::hd2::hd3::tail => {
|
||||
val List(x, y, z) = sort_1(hd1::hd2::hd3::Nil, Nil);
|
||||
val Pair(small, large) = tail.partition((e2) => lt(e2, y));
|
||||
val List(x, y, z) = sort_1(hd1::hd2::hd3::Nil, Nil)
|
||||
val Pair(small, large) = tail.partition((e2) => lt(e2, y))
|
||||
sort_1(x::small, y::sort_1(z::large, acc))
|
||||
}
|
||||
}
|
||||
|
@ -788,8 +795,8 @@ sealed abstract class List[+a] extends Seq[a] with CaseClass {
|
|||
else if (lt(z, y)) z::y::x::Nil
|
||||
else y::z::x::Nil
|
||||
case hd1::hd2::hd3::tail => {
|
||||
val List(x, y, z) = sort_1(hd1::hd2::hd3::Nil, Nil);
|
||||
val Pair(small,large) = tail.partition((e2) => lt(e2, y));
|
||||
val List(x, y, z) = sort_1(hd1::hd2::hd3::Nil, Nil)
|
||||
val Pair(small,large) = tail.partition((e2) => lt(e2, y))
|
||||
sort_1(x::small, y::sort_1(z::large, Nil));
|
||||
}
|
||||
}
|
||||
|
@ -970,16 +977,16 @@ sealed abstract class List[+a] extends Seq[a] with CaseClass {
|
|||
val b = new ListBuffer[Pair[a,int]]
|
||||
var these = this
|
||||
var idx = 0
|
||||
|
||||
|
||||
while(!these.isEmpty) {
|
||||
b += Pair(these.head, idx)
|
||||
these = these.tail
|
||||
idx = idx + 1
|
||||
}
|
||||
|
||||
|
||||
b.toList
|
||||
}
|
||||
|
||||
|
||||
/** Returns a list formed from this list and the specified list
|
||||
* <code>that</code> by associating each element of the former with
|
||||
* the element at the same position in the latter.
|
||||
|
@ -1053,7 +1060,7 @@ sealed abstract class List[+a] extends Seq[a] with CaseClass {
|
|||
* @return the list of elements contained both in this list and
|
||||
* in the given list <code>that</code>.
|
||||
*/
|
||||
def intersect[b >: a](that: List[b]): List[b] = filter(x => that contains x);
|
||||
def intersect[b >: a](that: List[b]): List[b] = filter(x => that contains x)
|
||||
|
||||
/** Removes redundant elements from the list. Uses the method <code>==</code>
|
||||
* to decide if two elements are identical.
|
||||
|
@ -1080,9 +1087,9 @@ sealed abstract class List[+a] extends Seq[a] with CaseClass {
|
|||
*/
|
||||
[SerialVersionUID(0 - 8256821097970055419L)]
|
||||
case object Nil extends List[Nothing] {
|
||||
override def isEmpty = true;
|
||||
def head: All = error("head of empty list");
|
||||
def tail: List[Nothing] = error("tail of empty list");
|
||||
override def isEmpty = true
|
||||
def head: All = error("head of empty list")
|
||||
def tail: List[Nothing] = error("tail of empty list")
|
||||
}
|
||||
|
||||
/** A non empty list characterized by a head and a tail.
|
||||
|
@ -1092,7 +1099,7 @@ case object Nil extends List[Nothing] {
|
|||
*/
|
||||
[SerialVersionUID(0L - 8476791151983527571L)]
|
||||
final case class ::[b](hd: b, private[scala] var tl: List[b]) extends List[b] {
|
||||
def head = hd;
|
||||
def tail = tl;
|
||||
override def isEmpty: boolean = false;
|
||||
def head = hd
|
||||
def tail = tl
|
||||
override def isEmpty: boolean = false
|
||||
}
|
||||
|
|
|
@ -9,8 +9,7 @@
|
|||
// $Id$
|
||||
|
||||
|
||||
package scala.collection.mutable;
|
||||
|
||||
package scala.collection.mutable
|
||||
|
||||
/** This class implements mutable maps using a hashtable.
|
||||
*
|
||||
|
@ -18,21 +17,20 @@ package scala.collection.mutable;
|
|||
* @version 1.0, 08/07/2003
|
||||
*/
|
||||
[serializable]
|
||||
class HashMap[A, B] extends Map[A,B] with HashTable[A] with DefaultMapModel[A,B]
|
||||
{
|
||||
class HashMap[A, B] extends Map[A,B] with HashTable[A] with DefaultMapModel[A,B] {
|
||||
|
||||
def -=(key: A): Unit = removeEntry(key);
|
||||
|
||||
protected def entryKey(e: Entry) = e.key;
|
||||
|
||||
override def clear = {
|
||||
initTable(table);
|
||||
tableSize = 0;
|
||||
}
|
||||
def -=(key: A): Unit = removeEntry(key)
|
||||
|
||||
override def clone(): Map[A, B] = {
|
||||
val res = new HashMap[A, B];
|
||||
res ++= this;
|
||||
res
|
||||
}
|
||||
protected def entryKey(e: Entry) = e.key
|
||||
|
||||
override def clear = {
|
||||
initTable(table)
|
||||
tableSize = 0
|
||||
}
|
||||
|
||||
override def clone(): Map[A, B] = {
|
||||
val res = new HashMap[A, B]
|
||||
res ++= this
|
||||
res
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,8 +9,7 @@
|
|||
// $Id$
|
||||
|
||||
|
||||
package scala.collection.mutable;
|
||||
|
||||
package scala.collection.mutable
|
||||
|
||||
/** This class implements mutable sets using a hashtable.
|
||||
*
|
||||
|
@ -20,32 +19,32 @@ package scala.collection.mutable;
|
|||
[serializable]
|
||||
class HashSet[A] extends Set[A] with HashTable[A] {
|
||||
|
||||
def contains(elem: A): Boolean = findEntry(elem) match {
|
||||
case None => false
|
||||
case Some(_) => true
|
||||
}
|
||||
|
||||
def +=(elem: A): Unit = findEntry(elem) match {
|
||||
case None => addEntry(elem);
|
||||
case Some(_) =>
|
||||
}
|
||||
|
||||
def -=(elem: A): Unit = removeEntry(elem);
|
||||
|
||||
def elements = entries;
|
||||
|
||||
def clear = {
|
||||
initTable(table);
|
||||
tableSize = 0;
|
||||
}
|
||||
|
||||
protected type Entry = A;
|
||||
|
||||
protected def entryKey(e: Entry) = e;
|
||||
|
||||
override def clone(): Set[A] = {
|
||||
val res = new HashSet[A];
|
||||
res ++= this;
|
||||
res
|
||||
}
|
||||
def contains(elem: A): Boolean = findEntry(elem) match {
|
||||
case None => false
|
||||
case Some(_) => true
|
||||
}
|
||||
|
||||
def +=(elem: A): Unit = findEntry(elem) match {
|
||||
case None => addEntry(elem)
|
||||
case Some(_) =>
|
||||
}
|
||||
|
||||
def -=(elem: A): Unit = removeEntry(elem)
|
||||
|
||||
def elements = entries
|
||||
|
||||
def clear = {
|
||||
initTable(table)
|
||||
tableSize = 0
|
||||
}
|
||||
|
||||
protected type Entry = A
|
||||
|
||||
protected def entryKey(e: Entry) = e
|
||||
|
||||
override def clone(): Set[A] = {
|
||||
val res = new HashSet[A]
|
||||
res ++= this
|
||||
res
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,8 +9,7 @@
|
|||
// $Id$
|
||||
|
||||
|
||||
package scala.collection.mutable;
|
||||
|
||||
package scala.collection.mutable
|
||||
|
||||
/** This class can be used to construct data structures that are based
|
||||
* on hashtables. Class <code>HashTable[A]</code> implements a hashtable
|
||||
|
@ -31,119 +30,115 @@ package scala.collection.mutable;
|
|||
*/
|
||||
trait HashTable[A] extends AnyRef {
|
||||
|
||||
/** The load factor for the hash table.
|
||||
*/
|
||||
protected val loadFactor: Float = 0.75f;
|
||||
|
||||
/** The initial size of the hash table.
|
||||
*/
|
||||
protected val initialSize: Int = 16;
|
||||
|
||||
/** The initial threshold
|
||||
*/
|
||||
protected val initialThreshold: Int = newThreshold(initialSize);
|
||||
|
||||
/** The actual hash table.
|
||||
*/
|
||||
protected var table: Array[List[Entry]] = new Array(initialSize);
|
||||
initTable(table);
|
||||
|
||||
/** The number of mappings contained in this hash table.
|
||||
*/
|
||||
protected var tableSize: Int = 0;
|
||||
|
||||
/** The next size value at which to resize (capacity * load factor).
|
||||
*/
|
||||
protected var threshold: Int = initialThreshold;
|
||||
|
||||
/** Returns the size of this hash map.
|
||||
*/
|
||||
def size = tableSize;
|
||||
|
||||
protected def findEntry(key: A): Option[Entry] =
|
||||
table(index(elemHashCode(key))).find(entryFor(key));
|
||||
|
||||
protected def addEntry(e: Entry): Unit = {
|
||||
val h = index(elemHashCode(entryKey(e)));
|
||||
table(h) = e :: table(h);
|
||||
tableSize = tableSize + 1;
|
||||
if (tableSize > threshold)
|
||||
resize(2 * table.length);
|
||||
/** The load factor for the hash table.
|
||||
*/
|
||||
protected val loadFactor: Float = 0.75f
|
||||
|
||||
/** The initial size of the hash table.
|
||||
*/
|
||||
protected val initialSize: Int = 16
|
||||
|
||||
/** The initial threshold
|
||||
*/
|
||||
protected val initialThreshold: Int = newThreshold(initialSize)
|
||||
|
||||
/** The actual hash table.
|
||||
*/
|
||||
protected var table: Array[List[Entry]] = new Array(initialSize)
|
||||
initTable(table)
|
||||
|
||||
/** The number of mappings contained in this hash table.
|
||||
*/
|
||||
protected var tableSize: Int = 0
|
||||
|
||||
/** The next size value at which to resize (capacity * load factor).
|
||||
*/
|
||||
protected var threshold: Int = initialThreshold
|
||||
|
||||
/** Returns the size of this hash map.
|
||||
*/
|
||||
def size = tableSize
|
||||
|
||||
protected def findEntry(key: A): Option[Entry] =
|
||||
table(index(elemHashCode(key))).find(entryFor(key))
|
||||
|
||||
protected def addEntry(e: Entry): Unit = {
|
||||
val h = index(elemHashCode(entryKey(e)))
|
||||
table(h) = e :: table(h)
|
||||
tableSize = tableSize + 1
|
||||
if (tableSize > threshold)
|
||||
resize(2 * table.length)
|
||||
}
|
||||
|
||||
protected def removeEntry(key: A): Unit = findEntry(key) match {
|
||||
case None =>
|
||||
case Some(e) =>
|
||||
val idx = index(elemHashCode(key))
|
||||
table(idx) = table(idx).filter(e => !elemEquals(entryKey(e), key))
|
||||
tableSize = tableSize - 1
|
||||
}
|
||||
|
||||
protected type Entry
|
||||
|
||||
protected def entryKey(e: Entry): A
|
||||
|
||||
protected def entries: Iterator[Entry] = new Iterator[Entry] {
|
||||
val iterTable = table
|
||||
var idx = table.length - 1
|
||||
var xs = iterTable(idx)
|
||||
scan()
|
||||
def hasNext = !xs.isEmpty
|
||||
def next = {
|
||||
val res = xs.head
|
||||
xs = xs.tail
|
||||
scan()
|
||||
res
|
||||
}
|
||||
|
||||
protected def removeEntry(key: A): Unit = {
|
||||
val old = findEntry(key);
|
||||
old match {
|
||||
case None =>
|
||||
case Some(e) => {
|
||||
val idx = index(elemHashCode(key));
|
||||
table(idx) = table(idx).filter(e => !elemEquals(entryKey(e), key));
|
||||
tableSize = tableSize - 1;
|
||||
}
|
||||
}
|
||||
def scan(): Unit = if (xs.isEmpty && (idx > 0)) {
|
||||
idx = idx - 1
|
||||
xs = iterTable(idx)
|
||||
scan()
|
||||
}
|
||||
|
||||
protected type Entry;
|
||||
|
||||
protected def entryKey(e: Entry): A;
|
||||
|
||||
protected def entries: Iterator[Entry] = new Iterator[Entry] {
|
||||
val iterTable = table;
|
||||
var idx = table.length - 1;
|
||||
var xs = iterTable(idx);
|
||||
scan();
|
||||
def hasNext = !xs.isEmpty;
|
||||
def next = {
|
||||
val res = xs.head;
|
||||
xs = xs.tail;
|
||||
scan();
|
||||
res;
|
||||
}
|
||||
def scan(): Unit = if (xs.isEmpty && (idx > 0)) {
|
||||
idx = idx - 1;
|
||||
xs = iterTable(idx);
|
||||
scan();
|
||||
}
|
||||
}
|
||||
|
||||
private def entryFor(key: A) = { e: Entry => elemEquals(entryKey(e), key) }
|
||||
|
||||
protected def initTable(tb: Array[List[Entry]]): Unit = {
|
||||
var i = tb.length - 1
|
||||
while (i >= 0) {
|
||||
tb(i) = Nil
|
||||
i = i - 1
|
||||
}
|
||||
|
||||
private def entryFor(key: A) = { e: Entry => elemEquals(entryKey(e), key) }
|
||||
|
||||
protected def initTable(tb: Array[List[Entry]]): Unit = {
|
||||
var i = tb.length - 1;
|
||||
while (i >= 0) {
|
||||
tb(i) = Nil;
|
||||
i = i - 1;
|
||||
}
|
||||
}
|
||||
|
||||
private def newThreshold(size: Int) =
|
||||
(size * loadFactor).asInstanceOf[Int]
|
||||
|
||||
private def resize(newSize: Int) = {
|
||||
val newTable: Array[List[Entry]] = new Array(newSize)
|
||||
initTable(newTable)
|
||||
var i = table.length - 1
|
||||
while (i >= 0) {
|
||||
table(i).foreach { e => {
|
||||
val idx = improve(elemHashCode(entryKey(e))) & (newSize - 1)
|
||||
newTable(idx) = e :: newTable(idx)
|
||||
}}
|
||||
i = i - 1
|
||||
}
|
||||
|
||||
private def newThreshold(size: Int) =
|
||||
(size * loadFactor).asInstanceOf[Int];
|
||||
|
||||
private def resize(newSize: Int) = {
|
||||
val newTable: Array[List[Entry]] = new Array(newSize);
|
||||
initTable(newTable);
|
||||
var i = table.length - 1;
|
||||
while (i >= 0) {
|
||||
table(i).foreach { e => {
|
||||
val idx = improve(elemHashCode(entryKey(e))) & (newSize - 1);
|
||||
newTable(idx) = e :: newTable(idx);
|
||||
}};
|
||||
i = i - 1;
|
||||
}
|
||||
table = newTable;
|
||||
threshold = newThreshold(newSize);
|
||||
}
|
||||
|
||||
protected def elemEquals(key1: A, key2: A): Boolean = (key1 == key2);
|
||||
|
||||
protected def elemHashCode(key: A) = key.hashCode();
|
||||
|
||||
protected final def improve(hcode: Int) = {
|
||||
var h: Int = hcode + ~(hcode << 9);
|
||||
h = h ^ (h >>> 14);
|
||||
h = h + (h << 4);
|
||||
h ^ (h >>> 10);
|
||||
}
|
||||
|
||||
protected final def index(hcode: Int) = improve(hcode) & (table.length - 1);
|
||||
table = newTable
|
||||
threshold = newThreshold(newSize)
|
||||
}
|
||||
|
||||
protected def elemEquals(key1: A, key2: A): Boolean = (key1 == key2)
|
||||
|
||||
protected def elemHashCode(key: A) = key.hashCode()
|
||||
|
||||
protected final def improve(hcode: Int) = {
|
||||
var h: Int = hcode + ~(hcode << 9)
|
||||
h = h ^ (h >>> 14)
|
||||
h = h + (h << 4)
|
||||
h ^ (h >>> 10)
|
||||
}
|
||||
|
||||
protected final def index(hcode: Int) = improve(hcode) & (table.length - 1)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue