Skip to content

Commit 15652c1

Browse files
committed
Merge pull request #529 from adamwy/master
Fix typos in collections overview
2 parents aea051b + c98de53 commit 15652c1

File tree

6 files changed

+16
-20
lines changed

6 files changed

+16
-20
lines changed

overviews/collections/arrays.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ The `ArrayOps` object gets inserted automatically by the implicit conversion. So
6060

6161
where `intArrayOps` is the implicit conversion that was inserted previously. This raises the question how the compiler picked `intArrayOps` over the other implicit conversion to `WrappedArray` in the line above. After all, both conversions map an array to a type that supports a reverse method, which is what the input specified. The answer to that question is that the two implicit conversions are prioritized. The `ArrayOps` conversion has a higher priority than the `WrappedArray` conversion. The first is defined in the `Predef` object whereas the second is defined in a class `scala.LowPriorityImplicits`, which is inherited from `Predef`. Implicits in subclasses and subobjects take precedence over implicits in base classes. So if both conversions are applicable, the one in `Predef` is chosen. A very similar scheme works for strings.
6262

63-
So now you know how arrays can be compatible with sequences and how they can support all sequence operations. What about genericity? In Java you cannot write a `T[]` where `T` is a type parameter. How then is Scala's `Array[T]` represented? In fact a generic array like `Array[T]` could be at run-time any of Java's eight primitive array types `byte[]`, `short[]`, `char[]`, `int[]`, `long[]`, `float[]`, `double[]`, `boolean[]`, or it could be an array of objects. The only common run-time type encompassing all of these types is `AnyRef` (or, equivalently `java.lang.Object`), so that's the type to which the Scala compiler maps `Array[T]`. At run-time, when an element of an array of type `Array[T]` is accessed or updated there is a sequence of type tests that determine the actual array type, followed by the correct array operation on the Java array. These type tests slow down array operations somewhat. You can expect accesses to generic arrays to be three to four times slower than accesses to primitive or object arrays. This means that if you need maximal performance, you should prefer concrete over generic arrays. Representing the generic array type is not enough, however, There must also be a way to create generic arrays. This is an even harder problem, which requires a little bit of help from you. To illustrate the problem, consider the following attempt to write a generic method that creates an array.
63+
So now you know how arrays can be compatible with sequences and how they can support all sequence operations. What about genericity? In Java you cannot write a `T[]` where `T` is a type parameter. How then is Scala's `Array[T]` represented? In fact a generic array like `Array[T]` could be at run-time any of Java's eight primitive array types `byte[]`, `short[]`, `char[]`, `int[]`, `long[]`, `float[]`, `double[]`, `boolean[]`, or it could be an array of objects. The only common run-time type encompassing all of these types is `AnyRef` (or, equivalently `java.lang.Object`), so that's the type to which the Scala compiler maps `Array[T]`. At run-time, when an element of an array of type `Array[T]` is accessed or updated there is a sequence of type tests that determine the actual array type, followed by the correct array operation on the Java array. These type tests slow down array operations somewhat. You can expect accesses to generic arrays to be three to four times slower than accesses to primitive or object arrays. This means that if you need maximal performance, you should prefer concrete over generic arrays. Representing the generic array type is not enough, however, there must also be a way to create generic arrays. This is an even harder problem, which requires a little bit of help from you. To illustrate the problem, consider the following attempt to write a generic method that creates an array.
6464

6565
// this is wrong!
6666
def evenElems[T](xs: Vector[T]): Array[T] = {
@@ -115,4 +115,3 @@ What happened here is that the `evenElems` demands a class manifest for the type
115115
This example also shows that the context bound in the definition of `U` is just a shorthand for an implicit parameter named here `evidence$1` of type `ClassManifest[U]`.
116116

117117
In summary, generic array creation demands class manifests. So whenever creating an array of a type parameter `T`, you also need to provide an implicit class manifest for `T`. The easiest way to do this is to declare the type parameter with a `ClassManifest` context bound, as in `[T: ClassManifest]`.
118-

overviews/collections/iterators.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ An iterator is not a collection, but rather a way to access the elements of a co
1313

1414
The most straightforward way to "step through" all the elements returned by an iterator `it` uses a while-loop:
1515

16-
while (it.hasNext)
16+
while (it.hasNext)
1717
println(it.next())
1818

1919
Iterators in Scala also provide analogues of most of the methods that you find in the `Traversable`, `Iterable` and `Seq` classes. For instance, they provide a `foreach` method which executes a given procedure on each element returned by an iterator. Using `foreach`, the loop above could be abbreviated to:
@@ -24,7 +24,7 @@ As always, for-expressions can be used as an alternate syntax for expressions in
2424

2525
for (elem <- it) println(elem)
2626

27-
There's an important difference between the foreach method on iterators and the same method on traversable collections: When called on an iterator, `foreach` will leave the iterator at its end when it is done. So calling `next` again on the same iterator will fail with a `NoSuchElementException`. By contrast, when called on on a collection, `foreach` leaves the number of elements in the collection unchanged (unless the passed function adds to removes elements, but this is discouraged, because it may lead to surprising results).
27+
There's an important difference between the foreach method on iterators and the same method on traversable collections: When called on an iterator, `foreach` will leave the iterator at its end when it is done. So calling `next` again on the same iterator will fail with a `NoSuchElementException`. By contrast, when called on a collection, `foreach` leaves the number of elements in the collection unchanged (unless the passed function adds to removes elements, but this is discouraged, because it may lead to surprising results).
2828

2929
The other operations that Iterator has in common with `Traversable` have the same property. For instance, iterators provide a `map` method, which returns a new iterator:
3030

@@ -151,7 +151,7 @@ Sometimes you want an iterator that can "look ahead", so that you can inspect th
151151

152152
def skipEmptyWordsNOT(it: Iterator[String]) =
153153
while (it.next().isEmpty) {}
154-
154+
155155
But looking at this code more closely, it's clear that this is wrong: The code will indeed skip leading empty strings, but it will also advance `it` past the first non-empty string!
156156

157157
The solution to this problem is to use a buffered iterator. Class [BufferedIterator](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/BufferedIterator.html) is a subclass of [Iterator](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/Iterator.html), which provides one extra method, `head`. Calling `head` on a buffered iterator will return its first element but will not advance the iterator. Using a buffered iterator, skipping empty words can be written as follows.

overviews/collections/migrating-from-scala-27.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ languages: [ja, zh-cn]
1212

1313
Porting your existing Scala applications to use the new collections should be almost automatic. There are only a couple of possible issues to take care of.
1414

15-
Generally, the old functionality of Scala 2.7 collections has been left in place. Some features have been deprecated, which means they will removed in some future release. You will get a _deprecation warning_ when you compile code that makes use of these features in Scala 2.8. In a few places deprecation was unfeasible, because the operation in question was retained in 2.8, but changed in meaning or performance characteristics. These cases will be flagged with _migration warnings_ when compiled under 2.8. To get full deprecation and migration warnings with suggestions how to change your code, pass the `-deprecation` and `-Xmigration` flags to `scalac` (note that `-Xmigration` is an extended option, so it starts with an `X`.) You can also pass the same options to the `scala` REPL to get the warnings in an interactive session. Example:
15+
Generally, the old functionality of Scala 2.7 collections has been left in place. Some features have been deprecated, which means they will removed in some future release. You will get a _deprecation warning_ when you compile code that makes use of these features in Scala 2.8. In a few places deprecation was unfeasible, because the operation in question was retained in 2.8, but changed in meaning or performance characteristics. These cases will be flagged with _migration warnings_ when compiled under 2.8. To get full deprecation and migration warnings with suggestions how to change your code, pass the `-deprecation` and `-Xmigration` flags to `scalac` (note that `-Xmigration` is an extended option, so it starts with an `X`). You can also pass the same options to the `scala` REPL to get the warnings in an interactive session. Example:
1616

1717
>scala -deprecation -Xmigration
1818
Welcome to Scala version 2.8.0.final
@@ -42,4 +42,3 @@ There are two parts of the old libraries which have been replaced wholesale, and
4242
2. Projections have been generalized and cleaned up and are now available as views. It seems that projections were used rarely, so not much code should be affected by this change.
4343

4444
So, if your code uses either `jcl` or projections there might be some minor rewriting to do.
45-

overviews/collections/overview.md

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,8 @@ versions of collections is to import just the package
6969

7070
import scala.collection.mutable
7171

72-
Then a word like `Set` without a prefix still refers to an an immutable collection,
73-
whereas `mutable.Set` refers to the mutable counterpart.
72+
Then a word like `Set` without a prefix still refers to an immutable collection,
73+
whereas `mutable.Set` refers to the mutable counterpart.
7474

7575
The last package in the collection hierarchy is `collection.generic`. This
7676
package contains building blocks for implementing
@@ -82,19 +82,19 @@ classes in `generic` only in exceptional circumstances.
8282
For convenience and backwards compatibility some important types have
8383
aliases in the `scala` package, so you can use them by their simple
8484
names without needing an import. An example is the `List` type, which
85-
can be accessed alternatively as
85+
can be accessed alternatively as
8686

8787
scala.collection.immutable.List // that's where it is defined
8888
scala.List // via the alias in the scala package
89-
List // because scala._
89+
List // because scala._
9090
// is always automatically imported
9191

92-
Other types so aliased are
92+
Other types so aliased are
9393
[Traversable](http://www.scala-lang.org/api/current/scala/collection/Traversable.html), [Iterable](http://www.scala-lang.org/api/current/scala/collection/Iterable.html), [Seq](http://www.scala-lang.org/api/current/scala/collection/Seq.html), [IndexedSeq](http://www.scala-lang.org/api/current/scala/collection/IndexedSeq.html), [Iterator](http://www.scala-lang.org/api/current/scala/collection/Iterator.html), [Stream](http://www.scala-lang.org/api/current/scala/collection/immutable/Stream.html), [Vector](http://www.scala-lang.org/api/current/scala/collection/immutable/Vector.html), [StringBuilder](http://www.scala-lang.org/api/current/scala/collection/mutable/StringBuilder.html), and [Range](http://www.scala-lang.org/api/current/scala/collection/immutable/Range.html).
9494

9595
The following figure shows all collections in package
9696
`scala.collection`. These are all high-level abstract classes or traits, which
97-
generally have mutable as well as immutable implementations.
97+
generally have mutable as well as immutable implementations.
9898

9999
[<img src="{{ site.baseurl }}/resources/images/collections.png" width="550">]({{ site.baseurl }}/resources/images/collections.png)
100100

@@ -130,7 +130,7 @@ All these collections get displayed with `toString` in the same way they are wri
130130

131131
All collections support the API provided by `Traversable`, but specialize types wherever this makes sense. For instance the `map` method in class `Traversable` returns another `Traversable` as its result. But this result type is overridden in subclasses. For instance, calling `map` on a `List` yields again a `List`, calling it on a `Set` yields again a `Set` and so on.
132132

133-
scala> List(1, 2, 3) map (_ + 1)
133+
scala> List(1, 2, 3) map (_ + 1)
134134
res0: List[Int] = List(2, 3, 4)
135135
scala> Set(1, 2, 3) map (_ * 2)
136136
res0: Set[Int] = Set(2, 4, 6)
@@ -139,4 +139,4 @@ This behavior which is implemented everywhere in the collections libraries is ca
139139

140140
Most of the classes in the collections hierarchy exist in three variants: root, mutable, and immutable. The only exception is the Buffer trait which only exists as a mutable collection.
141141

142-
In the following, we will review these classes one by one.
142+
In the following, we will review these classes one by one.

overviews/collections/performance-characteristics.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ The first table treats sequence types--both immutable and mutable--with the foll
6969
| **head** | Selecting the first element of the sequence. |
7070
| **tail** | Producing a new sequence that consists of all elements except the first one. |
7171
| **apply** | Indexing. |
72-
| **update** | Functional update (with `updated`) for immutable sequences, side-effecting update (with `update` for mutable sequences. |
72+
| **update** | Functional update (with `updated`) for immutable sequences, side-effecting update (with `update` for mutable sequences). |
7373
| **prepend**| Adding an element to the front of the sequence. For immutable sequences, this produces a new sequence. For mutable sequences it modified the existing sequence. |
7474
| **append** | Adding an element and the end of the sequence. For immutable sequences, this produces a new sequence. For mutable sequences it modified the existing sequence. |
7575
| **insert** | Inserting an element at an arbitrary position in the sequence. This is only supported directly for mutable sequences. |
@@ -82,4 +82,3 @@ The second table treats mutable and immutable sets and maps with the following o
8282
| **add** | Adding a new element to a set or key/value pair to a map. |
8383
| **remove** | Removing an element from a set or a key from a map. |
8484
| **min** | The smallest element of the set, or the smallest key of a map. |
85-

overviews/collections/sets.md

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ languages: [ja, zh-cn]
1111

1212
`Set`s are `Iterable`s that contain no duplicate elements. The operations on sets are summarized in the following table for general sets and in the table after that for mutable sets. They fall into the following categories:
1313

14-
* **Tests** `contains`, `apply`, `subsetOf`. The `contains` method asks whether a set contains a given element. The `apply` method for a set is the same as `contains`, so `set(elem)` is the same as `set contains elem`. That means sets can also be used as test functions that return true for the elements they contain.
14+
* **Tests** `contains`, `apply`, `subsetOf`. The `contains` method asks whether a set contains a given element. The `apply` method for a set is the same as `contains`, so `set(elem)` is the same as `set contains elem`. That means sets can also be used as test functions that return true for the elements they contain.
1515

1616
For example:
1717

@@ -97,7 +97,7 @@ We used `+=` and `-=` on a `var` of type `immutable.Set`. A statement such as `s
9797
scala> s -= 2
9898
res4: s.type = Set(1, 4, 3)
9999

100-
The end effect is very similar to the previous interaction; we start with a `Set(1, 2, 3)` end end up with a `Set(1, 3, 4)`. However, even though the statements look the same as before, they do something different. `s += 4` now invokes the `+=` method on the mutable set value `s`, changing the set in place. Likewise, `s -= 2` now invokes the `-=` method on the same set.
100+
The end effect is very similar to the previous interaction; we start with a `Set(1, 2, 3)` and end up with a `Set(1, 3, 4)`. However, even though the statements look the same as before, they do something different. `s += 4` now invokes the `+=` method on the mutable set value `s`, changing the set in place. Likewise, `s -= 2` now invokes the `-=` method on the same set.
101101

102102
Comparing the two interactions shows an important principle. You often can replace a mutable collection stored in a `val` by an immutable collection stored in a `var`, and _vice versa_. This works at least as long as there are no alias references to the collection through which one can observe whether it was updated in place or whether a new collection was created.
103103

@@ -146,4 +146,3 @@ Sorted sets also support ranges of elements. For instance, the `range` method re
146146
Bitsets are sets of non-negative integer elements that are implemented in one or more words of packed bits. The internal representation of a [BitSet](http://www.scala-lang.org/api/current/scala/collection/BitSet.html) uses an array of `Long`s. The first `Long` covers elements from 0 to 63, the second from 64 to 127, and so on (Immutable bitsets of elements in the range of 0 to 127 optimize the array away and store the bits directly in a one or two `Long` fields.) For every `Long`, each of its 64 bits is set to 1 if the corresponding element is contained in the set, and is unset otherwise. It follows that the size of a bitset depends on the largest integer that's stored in it. If `N` is that largest integer, then the size of the set is `N/64` `Long` words, or `N/8` bytes, plus a small number of extra bytes for status information.
147147

148148
Bitsets are hence more compact than other sets if they contain many small elements. Another advantage of bitsets is that operations such as membership test with `contains`, or element addition and removal with `+=` and `-=` are all extremely efficient.
149-

0 commit comments

Comments
 (0)