1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
|
/* __ *\
** ________ ___ / / ___ Scala API **
** / __/ __// _ | / / / _ | (c) 2003-2007, LAMP/EPFL **
** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
** /____/\___/_/ |_/____/_/ | | **
** |/ **
\* */
// $Id$
package scala.collection.immutable
import Predef._
/** <p>An object for creating immutable maps. These are implemented using
* <a href="HashMap.html">immutable hash maps</a>.
* </p>*/
object Map {
def empty[A, B]: Map[A, B] = new EmptyMap[A, B]
def apply[A, B](elems: (A, B)*) = empty[A, B] ++ elems
}
/** <p>
* This class defines the interface for immutable maps. Operations
* on an immutable map leave the original map unchanged, and return
* a new map if needed.
* </p>
* <p>
* Concrete map implementations have to provide functionality for
* the abstract methods in <a href="../Map.html" target="contentFrame">
* <code>scala.collection.Map</code></a> as well as for
* <code>factory</code>, <code>update</code>, and <code>-</code>.
* </p>
*
* @author Matthias Zenger
* @author Erik Stenman
* @author Martin Odersky
* @version 1.2, 31/06/2006
*/
trait Map[A, +B] extends collection.Map[A, B] {
/** This method returns a new map instance of the same class
* mapping keys of the same type to values of type <code>C</code>.
*/
def empty[C]: Map[A, C]
/** This method allows one to create a new map with an
* additional mapping from <code>key</code>
* to <code>value</code>. If the map contains already a
* mapping for <code>key</code>, it will be overridden by this
* function.
*
* @param key ...
* @param value ...
* @return the created map
* @deprecated use <code>+({A, B})</code> instead
*/
def update [B1 >: B] (key: A, value: B1): Map[A, B1]
/** Add a key/value pair to this 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)): Map[A, B1] = update(kv._1, kv._2)
/** Add two or more key/value pairs to this map.
* @param kv1 the first key/value pair.
* @param kv2 the second key/value pair.
* @param kvs the remaining key/value pairs.
* @return A new map with the new bindings added
*/
def + [B1 >: B] (kv1: (A, B1), kv2: (A, B1), kvs: (A, B1)*): Map[A, B1] =
this + kv1 + kv2 ++ kvs
/** Add a sequence of key/value pairs to this map.
* @param kvs the iterable object containing all key/value pairs.
* @return A new map with the new bindings added
*/
def ++ [B1 >: B] (kvs: Iterable[(A, B1)]): Map[A, B1] =
((this: Map[A, B1]) /: kvs) ((m, kv) => m + kv)
/** Add a sequence of key/value pairs to this map.
* @param kvs the iterator containing all key/value pairs.
* @return A new map with the new bindings added
*/
def ++ [B1 >: B] (kvs: Iterator[(A, B1)]): Map[A, B1] =
((this: Map[A, B1]) /: kvs) ((m, kv) => m + kv)
/** Remove a key from this map
* @param key the key to be removed
* @return If the map does not contain a binding for <code>key</code>
* it is returned unchanged. Otherwise, return a new map
* without a binding for <code>key</code>
*/
def - (key: A): Map[A, B]
/** Remove two or more keys from this map
* @param key1 the first key to be removed
* @param key2 the second key to be removed
* @param keys the remaining keys to be removed
* @return A map without bindings for <code>keys</code>
* If the map is mutable, the bindings are removed in place
* and the map itself is returned.
* If the map is immutable, a new map with the bindings removed is returned.
*/
def - (key1: A, key2: A, keys: A*): Map[A, B] =
this - key1 - key2 -- keys
/** Remove a sequence of keys from this map
* @param keys the keys to be removed
* @return A map without bindings for the given keys.
* If the map is mutable, the bindings are removed in place
* and the map itself is returned.
* If the map is immutable, a new map with the bindings removed is returned.
*/
def -- (keys: Iterable[A]): Map[A, B] = this -- keys.elements
/** Remove a sequence of keys from this map
* @param keys the keys to be removed
* @return A map without bindings for the given keys.
* If the map is mutable, the bindings are removed in place
* and the map itself is returned.
* If the map is immutable, a new map with the bindings removed is returned.
*/
def -- (keys: Iterator[A]): Map[A, B] =
(this /: keys) ((m, key) => m - key)
/** The same map with a given default function */
def withDefault[B1 >: B](d: A => B1): Map[A, B1] = new Map[A, B1] {
def size = Map.this.size
def get(key: A) = Map.this.get(key)
def elements = Map.this.elements
def empty[C] = Map.this.empty
def update [B2 >: B1](key: A, value: B2): Map[A, B2] =
Map.this.update(key, value) withDefault d
def -(key: A): Map[A, B1] = Map.this - key withDefault d
override def default(key: A): B1 = d(key)
}
/** The same map with a given default value */
def withDefaultValue[B1 >: B](d: B1): Map[A, B1] = withDefault(x => d)
/** This function transforms all the values of mappings contained
* in this map with function <code>f</code>.
*
* @param f A function over keys and values
* @return the updated map
*/
def transform[C](f: (A, B) => C): Map[A, C] = {
var res = empty[C]
foreach { case (key, value) => res = res.update(key, f(key, value)) }
res
}
/** This method removes all the mappings for which the predicate
* <code>p</code> returns <code>false</code>.
*
* @param p A prediacte over key-value pairs
* @return the updated map
*/
override def filter(p: ((A, B)) => Boolean): Map[A, B] = {
var res = this
foreach {
case kv @ (key, _) => if (!p(kv)) { res = res - key }
}
res
}
/** <p>
* This method defines syntactic sugar for adding a
* mapping. It is typically used in the following way:
* </p>
* <pre>
* map + key -> value
* </pre>
* @deprecated use <code>+({A, B})</code> instead
*/
@deprecated def +(key: A): MapTo = new MapTo(key)
/** <code>incl</code> can be used to add many mappings at the same time
* to the map. The method assumes that a mapping is represented
* by a <code>Pair</code> object who's first component denotes the
* key, and who's second component refers to the value.
*
* @param mappings ...
* @return ...
* @deprecated use <code>+</code> instead
*/
@deprecated def incl[B1 >: B](mappings: (A, B1)*): Map[A, B1] = incl(mappings)
/** <code>incl</code> can be used to add many mappings at the same time
* to the map. The method assumes that each mapping is represented
* by an Iterator over <code>Pair</code> objects who's first component
* denotes the key, and who's second component refers to the value.
*
* @deprecated use <code>++</code> instead
*/
@deprecated def incl[B1 >: B](map: Iterable[(A, B1)]): Map[A, B1] = {
val iter = map.elements
var res: Map[A, B1] = this
while (iter.hasNext) {
val (key, value) = iter.next
res = res.update(key, value)
}
res
}
/** This method will return a map where all the mappings
* for the given sequence of keys are removed from the map.
*
* @param keys ...
* @return the updated map
* @deprecated use <code>-</code> instead
*/
@deprecated def excl(keys: A*): Map[A, B] = excl(keys)
/** This method removes all the mappings for keys provided by an
* iterator over the elements of the <code>keys</code> object.
*
* @param keys ...
* @return the updated map
* @deprecated use <code>--</code> instead
*/
@deprecated def excl(keys: Iterable[A]): Map[A, B] = {
val iter = keys.elements
var res = this
while (iter.hasNext) {
res = res - iter.next
}
res
}
/** This method controls how a mapping is represented in the string
* representation provided by method <code>toString</code>.
*
* @param p ...
* @return the string representation of a map entry
*/
@deprecated def mappingToString[B1 >: B](p: (A, B1)) =
p._1.toString() + " -> " + p._2
/** @deprecated use <code>+({A, B})</code> instead
*/
@deprecated class MapTo(key: A) {
def -> [B1 >: B](value: B1) = update(key, value)
}
}
|