diff --git a/_config.yml b/_config.yml index 32288ccccc..e7564efd1a 100644 --- a/_config.yml +++ b/_config.yml @@ -15,8 +15,8 @@ keywords: - Document - Guide -scala-version: 2.12.8 -scala-213-version: 2.13.0-M5 +scala-version: 2.13.0 +scala-212-version: 2.12.8 collections: style: diff --git a/_overviews/collections-2.13/concrete-immutable-collection-classes.md b/_overviews/collections-2.13/concrete-immutable-collection-classes.md index e3c8f68556..af8ed0b95c 100644 --- a/_overviews/collections-2.13/concrete-immutable-collection-classes.md +++ b/_overviews/collections-2.13/concrete-immutable-collection-classes.md @@ -16,11 +16,11 @@ Scala provides many concrete immutable collection classes for you to choose from ## Lists -A [List](http://www.scala-lang.org/api/{{ site.scala-213-version }}/scala/collection/immutable/List.html) is a finite immutable sequence. They provide constant-time access to their first element as well as the rest of the list, and they have a constant-time cons operation for adding a new element to the front of the list. Many other operations take linear time. +A [List](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/immutable/List.html) is a finite immutable sequence. They provide constant-time access to their first element as well as the rest of the list, and they have a constant-time cons operation for adding a new element to the front of the list. Many other operations take linear time. ## LazyLists -A [LazyList](http://www.scala-lang.org/api/{{ site.scala-213-version }}/scala/collection/immutable/LazyList.html) is like a list except that its elements are computed lazily. Because of this, a lazy list can be infinitely long. Only those elements requested are computed. Otherwise, lazy lists have the same performance characteristics as lists. +A [LazyList](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/immutable/LazyList.html) is like a list except that its elements are computed lazily. Because of this, a lazy list can be infinitely long. Only those elements requested are computed. Otherwise, lazy lists have the same performance characteristics as lists. Whereas lists are constructed with the `::` operator, lazy lists are constructed with the similar-looking `#::`. Here is a simple example of a lazy list containing the integers 1, 2, and 3: @@ -48,7 +48,7 @@ Here are the first few elements of the Fibonacci sequence starting with two ones Lists are very efficient when the algorithm processing them is careful to only process their heads. Accessing, adding, and removing the head of a list takes only constant time, whereas accessing or modifying elements later in the list takes time linear in the depth into the list. -[ArraySeq](http://www.scala-lang.org/api/{{ site.scala-213-version }}/scala/collection/immutable/ArraySeq.html) is a +[ArraySeq](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/immutable/ArraySeq.html) is a collection type (introduced in Scala 2.13) that addresses the inefficiency for random access on lists. ArraySeqs allow accessing any element of the collection in constant time. As a result, algorithms using ArraySeqs do not have to be careful about accessing just the head of the collection. They can access elements at arbitrary locations, @@ -87,7 +87,7 @@ We have seen in the previous sections that `List` and `ArraySeq` are efficient d use cases but they are also inefficient in other use cases: for instance, prepending an element is constant for `List`, but linear for `ArraySeq`, and, conversely, indexed access is constant for `ArraySeq` but linear for `List`. -[Vector](http://www.scala-lang.org/api/{{ site.scala-213-version }}/scala/collection/immutable/Vector.html) is a collection type that provides good performance for all its operations. Vectors allow accessing any element of the sequence in "effectively" constant time. It's a larger constant than for access to the head of a List or for reading an element of an ArraySeq, but it's a constant nonetheless. As a result, algorithms using vectors do not have to be careful about accessing just the head of the sequence. They can access and modify elements at arbitrary locations, and thus they can be much more convenient to write. +[Vector](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/immutable/Vector.html) is a collection type that provides good performance for all its operations. Vectors allow accessing any element of the sequence in "effectively" constant time. It's a larger constant than for access to the head of a List or for reading an element of an ArraySeq, but it's a constant nonetheless. As a result, algorithms using vectors do not have to be careful about accessing just the head of the sequence. They can access and modify elements at arbitrary locations, and thus they can be much more convenient to write. Vectors are built and modified just like any other sequence. @@ -112,7 +112,7 @@ Because vectors strike a good balance between fast random selections and fast ra ## Immutable Queues -A [Queue](http://www.scala-lang.org/api/{{ site.scala-213-version }}/scala/collection/immutable/Queue.html) is a first-in-first-out sequence. You enqueue an element onto a queue with `enqueue`, and dequeue an element with `dequeue`. These operations are constant time. +A [Queue](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/immutable/Queue.html) is a first-in-first-out sequence. You enqueue an element onto a queue with `enqueue`, and dequeue an element with `dequeue`. These operations are constant time. Here's how you can create an empty immutable queue: @@ -140,7 +140,7 @@ Note that `dequeue` returns a pair consisting of the element removed and the res ## Ranges -A [Range](http://www.scala-lang.org/api/{{ site.scala-213-version }}/scala/collection/immutable/Range.html) is an ordered sequence of integers that are equally spaced apart. For example, "1, 2, 3," is a range, as is "5, 8, 11, 14." To create a range in Scala, use the predefined methods `to` and `by`. +A [Range](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/immutable/Range.html) is an ordered sequence of integers that are equally spaced apart. For example, "1, 2, 3," is a range, as is "5, 8, 11, 14." To create a range in Scala, use the predefined methods `to` and `by`. scala> 1 to 3 res2: scala.collection.immutable.Range.Inclusive = Range(1, 2, 3) @@ -156,7 +156,7 @@ Ranges are represented in constant space, because they can be defined by just th ## Compressed Hash-Array Mapped Prefix-trees -Hash tries are a standard way to implement immutable sets and maps efficiently. [Compressed Hash-Array Mapped Prefix-trees](https://github.com/msteindorfer/oopsla15-artifact/) are a design for hash tries on the JVM which improves locality and makes sure the trees remain in a canonical and compact representation. They are supported by class [immutable.HashMap](http://www.scala-lang.org/api/{{ site.scala-213-version }}/scala/collection/immutable/HashMap.html). Their representation is similar to vectors in that they are also trees where every node has 32 elements or 32 subtrees. But the selection of these keys is now done based on hash code. For instance, to find a given key in a map, one first takes the hash code of the key. Then, the lowest 5 bits of the hash code are used to select the first subtree, followed by the next 5 bits and so on. The selection stops once all elements stored in a node have hash codes that differ from each other in the bits that are selected up to this level. +Hash tries are a standard way to implement immutable sets and maps efficiently. [Compressed Hash-Array Mapped Prefix-trees](https://github.com/msteindorfer/oopsla15-artifact/) are a design for hash tries on the JVM which improves locality and makes sure the trees remain in a canonical and compact representation. They are supported by class [immutable.HashMap](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/immutable/HashMap.html). Their representation is similar to vectors in that they are also trees where every node has 32 elements or 32 subtrees. But the selection of these keys is now done based on hash code. For instance, to find a given key in a map, one first takes the hash code of the key. Then, the lowest 5 bits of the hash code are used to select the first subtree, followed by the next 5 bits and so on. The selection stops once all elements stored in a node have hash codes that differ from each other in the bits that are selected up to this level. Hash tries strike a nice balance between reasonably fast lookups and reasonably efficient functional insertions (`+`) and deletions (`-`). That's why they underly Scala's default implementations of immutable maps and sets. In fact, Scala has a further optimization for immutable sets and maps that contain less than five elements. Sets and maps with one to four elements are stored as single objects that just contain the elements (or key/value pairs in the case of a map) as fields. The empty immutable set and the empty immutable map is in each case a single object - there's no need to duplicate storage for those because an empty immutable set or map will always stay empty. @@ -164,7 +164,7 @@ Hash tries strike a nice balance between reasonably fast lookups and reasonably Red-black trees are a form of balanced binary tree where some nodes are designated "red" and others designated "black." Like any balanced binary tree, operations on them reliably complete in time logarithmic to the size of the tree. -Scala provides implementations of immutable sets and maps that use a red-black tree internally. Access them under the names [TreeSet](http://www.scala-lang.org/api/{{ site.scala-213-version }}/scala/collection/immutable/TreeSet.html) and [TreeMap](http://www.scala-lang.org/api/{{ site.scala-213-version }}/scala/collection/immutable/TreeMap.html). +Scala provides implementations of immutable sets and maps that use a red-black tree internally. Access them under the names [TreeSet](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/immutable/TreeSet.html) and [TreeMap](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/immutable/TreeMap.html). scala> scala.collection.immutable.TreeSet.empty[Int] @@ -176,7 +176,7 @@ Red-black trees are the standard implementation of `SortedSet` in Scala, because ## Immutable BitSets -A [BitSet](http://www.scala-lang.org/api/{{ site.scala-213-version }}/scala/collection/immutable/BitSet.html) represents a collection of small integers as the bits of a larger integer. For example, the bit set containing 3, 2, and 0 would be represented as the integer 1101 in binary, which is 13 in decimal. +A [BitSet](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/immutable/BitSet.html) represents a collection of small integers as the bits of a larger integer. For example, the bit set containing 3, 2, and 0 would be represented as the integer 1101 in binary, which is 13 in decimal. Internally, bit sets use an array of 64-bit `Long`s. The first `Long` in the array is for integers 0 through 63, the second is for 64 through 127, and so on. Thus, bit sets are very compact so long as the largest integer in the set is less than a few hundred or so. @@ -193,7 +193,7 @@ Operations on bit sets are very fast. Testing for inclusion takes constant time. ## VectorMaps -A [VectorMap](http://www.scala-lang.org/api/{{ site.scala-213-version }}/scala/collection/immutable/VectorMap.html) represents +A [VectorMap](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/immutable/VectorMap.html) represents a map using both a `Vector` of keys and a `HashMap`. It provides an iterator that returns all the entries in their insertion order. @@ -217,7 +217,7 @@ order of elements into account. ## ListMaps -A [ListMap](http://www.scala-lang.org/api/{{ site.scala-213-version }}/scala/collection/immutable/ListMap.html) represents a map as a linked list of key-value pairs. In general, operations on a list map might have to iterate through the entire list. Thus, operations on a list map take time linear in the size of the map. In fact there is little usage for list maps in Scala because standard immutable maps are almost always faster. The only possible exception to this is if the map is for some reason constructed in such a way that the first elements in the list are selected much more often than the other elements. +A [ListMap](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/immutable/ListMap.html) represents a map as a linked list of key-value pairs. In general, operations on a list map might have to iterate through the entire list. Thus, operations on a list map take time linear in the size of the map. In fact there is little usage for list maps in Scala because standard immutable maps are almost always faster. The only possible exception to this is if the map is for some reason constructed in such a way that the first elements in the list are selected much more often than the other elements. scala> val map = scala.collection.immutable.ListMap(1->"one", 2->"two") map: scala.collection.immutable.ListMap[Int,java.lang.String] = diff --git a/_overviews/collections-2.13/concrete-mutable-collection-classes.md b/_overviews/collections-2.13/concrete-mutable-collection-classes.md index bcf855ddc6..f2cf39eb41 100644 --- a/_overviews/collections-2.13/concrete-mutable-collection-classes.md +++ b/_overviews/collections-2.13/concrete-mutable-collection-classes.md @@ -16,7 +16,7 @@ You've now seen the most commonly used immutable collection classes that Scala p ## Array Buffers -An [ArrayBuffer](http://www.scala-lang.org/api/{{ site.scala-213-version }}/scala/collection/mutable/ArrayBuffer.html) buffer holds an array and a size. Most operations on an array buffer have the same speed as for an array, because the operations simply access and modify the underlying array. Additionally, array buffers can have data efficiently added to the end. Appending an item to an array buffer takes amortized constant time. Thus, array buffers are useful for efficiently building up a large collection whenever the new items are always added to the end. +An [ArrayBuffer](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/mutable/ArrayBuffer.html) buffer holds an array and a size. Most operations on an array buffer have the same speed as for an array, because the operations simply access and modify the underlying array. Additionally, array buffers can have data efficiently added to the end. Appending an item to an array buffer takes amortized constant time. Thus, array buffers are useful for efficiently building up a large collection whenever the new items are always added to the end. scala> val buf = scala.collection.mutable.ArrayBuffer.empty[Int] buf: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer() @@ -29,7 +29,7 @@ An [ArrayBuffer](http://www.scala-lang.org/api/{{ site.scala-213-version }}/scal ## List Buffers -A [ListBuffer](http://www.scala-lang.org/api/{{ site.scala-213-version }}/scala/collection/mutable/ListBuffer.html) is like an array buffer except that it uses a linked list internally instead of an array. If you plan to convert the buffer to a list once it is built up, use a list buffer instead of an array buffer. +A [ListBuffer](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/mutable/ListBuffer.html) is like an array buffer except that it uses a linked list internally instead of an array. If you plan to convert the buffer to a list once it is built up, use a list buffer instead of an array buffer. scala> val buf = scala.collection.mutable.ListBuffer.empty[Int] buf: scala.collection.mutable.ListBuffer[Int] = ListBuffer() @@ -42,7 +42,7 @@ A [ListBuffer](http://www.scala-lang.org/api/{{ site.scala-213-version }}/scala/ ## StringBuilders -Just like an array buffer is useful for building arrays, and a list buffer is useful for building lists, a [StringBuilder](http://www.scala-lang.org/api/{{ site.scala-213-version }}/scala/collection/mutable/StringBuilder.html) is useful for building strings. String builders are so commonly used that they are already imported into the default namespace. Create them with a simple `new StringBuilder`, like this: +Just like an array buffer is useful for building arrays, and a list buffer is useful for building lists, a [StringBuilder](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/mutable/StringBuilder.html) is useful for building strings. String builders are so commonly used that they are already imported into the default namespace. Create them with a simple `new StringBuilder`, like this: scala> val buf = new StringBuilder buf: StringBuilder = @@ -55,7 +55,7 @@ Just like an array buffer is useful for building arrays, and a list buffer is us ## ArrayDeque -An [ArrayDeque](http://www.scala-lang.org/api/{{ site.scala-213-version }}/scala/collection/mutable/ArrayDeque.html) +An [ArrayDeque](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/mutable/ArrayDeque.html) is a sequence that supports efficient addition of elements in the front and in the end. It internally uses a resizable array. @@ -81,7 +81,7 @@ Scala provides mutable queues in addition to immutable ones. You use a `mQueue` ## Stacks -You saw immutable stacks earlier. There is also a mutable version, supported by class [mutable.Stack](http://www.scala-lang.org/api/{{ site.scala-213-version }}/scala/collection/mutable/Stack.html). It works exactly the same as the immutable version except that modifications happen in place. +You saw immutable stacks earlier. There is also a mutable version, supported by class [mutable.Stack](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/mutable/Stack.html). It works exactly the same as the immutable version except that modifications happen in place. scala> val stack = new scala.collection.mutable.Stack[Int] stack: scala.collection.mutable.Stack[Int] = Stack() @@ -104,13 +104,13 @@ You saw immutable stacks earlier. There is also a mutable version, supported by ## Mutable ArraySeqs -Array sequences are mutable sequences of fixed size which store their elements internally in an `Array[Object]`. They are implemented in Scala by class [ArraySeq](http://www.scala-lang.org/api/{{ site.scala-213-version }}/scala/collection/mutable/ArraySeq.html). +Array sequences are mutable sequences of fixed size which store their elements internally in an `Array[Object]`. They are implemented in Scala by class [ArraySeq](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/mutable/ArraySeq.html). You would typically use an `ArraySeq` if you want an array for its performance characteristics, but you also want to create generic instances of the sequence where you do not know the type of the elements and you do not have a `ClassTag` to provide it at run-time. These issues are explained in the section on [arrays]({{ site.baseurl }}/overviews/collections/arrays.html). ## Hash Tables -A hash table stores its elements in an underlying array, placing each item at a position in the array determined by the hash code of that item. Adding an element to a hash table takes only constant time, so long as there isn't already another element in the array that has the same hash code. Hash tables are thus very fast so long as the objects placed in them have a good distribution of hash codes. As a result, the default mutable map and set types in Scala are based on hash tables. You can access them also directly under the names [mutable.HashSet](http://www.scala-lang.org/api/{{ site.scala-213-version }}/scala/collection/mutable/HashSet.html) and [mutable.HashMap](http://www.scala-lang.org/api/{{ site.scala-213-version }}/scala/collection/mutable/HashMap.html). +A hash table stores its elements in an underlying array, placing each item at a position in the array determined by the hash code of that item. Adding an element to a hash table takes only constant time, so long as there isn't already another element in the array that has the same hash code. Hash tables are thus very fast so long as the objects placed in them have a good distribution of hash codes. As a result, the default mutable map and set types in Scala are based on hash tables. You can access them also directly under the names [mutable.HashSet](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/mutable/HashSet.html) and [mutable.HashMap](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/mutable/HashMap.html). Hash sets and maps are used just like any other set or map. Here are some simple examples: @@ -129,11 +129,11 @@ Iteration over a hash table is not guaranteed to occur in any particular order. ## Weak Hash Maps -A weak hash map is a special kind of hash map where the garbage collector does not follow links from the map to the keys stored in it. This means that a key and its associated value will disappear from the map if there is no other reference to that key. Weak hash maps are useful for tasks such as caching, where you want to re-use an expensive function's result if the function is called again on the same key. If keys and function results are stored in a regular hash map, the map could grow without bounds, and no key would ever become garbage. Using a weak hash map avoids this problem. As soon as a key object becomes unreachable, it's entry is removed from the weak hashmap. Weak hash maps in Scala are implemented by class [WeakHashMap](http://www.scala-lang.org/api/{{ site.scala-213-version }}/scala/collection/mutable/WeakHashMap.html) as a wrapper of an underlying Java implementation `java.util.WeakHashMap`. +A weak hash map is a special kind of hash map where the garbage collector does not follow links from the map to the keys stored in it. This means that a key and its associated value will disappear from the map if there is no other reference to that key. Weak hash maps are useful for tasks such as caching, where you want to re-use an expensive function's result if the function is called again on the same key. If keys and function results are stored in a regular hash map, the map could grow without bounds, and no key would ever become garbage. Using a weak hash map avoids this problem. As soon as a key object becomes unreachable, it's entry is removed from the weak hashmap. Weak hash maps in Scala are implemented by class [WeakHashMap](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/mutable/WeakHashMap.html) as a wrapper of an underlying Java implementation `java.util.WeakHashMap`. ## Concurrent Maps -A concurrent map can be accessed by several threads at once. In addition to the usual [Map](http://www.scala-lang.org/api/{{ site.scala-213-version }}/scala/collection/Map.html) operations, it provides the following atomic operations: +A concurrent map can be accessed by several threads at once. In addition to the usual [Map](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/Map.html) operations, it provides the following atomic operations: ### Operations in Class concurrent.Map @@ -144,11 +144,11 @@ A concurrent map can be accessed by several threads at once. In addition to the | `m.replace(k, old, new)` |Replaces value associated with key `k` to `new`, if it was previously bound to `old`. | | `m.replace (k, v)` |Replaces value associated with key `k` to `v`, if it was previously bound to some value.| -`concurrent.Map` is a trait in the Scala collections library. Currently, it has two implementations. The first one is Java's `java.util.concurrent.ConcurrentMap`, which can be converted automatically into a Scala map using the [standard Java/Scala collection conversions]({{ site.baseurl }}/overviews/collections/conversions-between-java-and-scala-collections.html). The second implementation is [TrieMap](http://www.scala-lang.org/api/{{ site.scala-213-version }}/scala/collection/concurrent/TrieMap.html), which is a lock-free implementation of a hash array mapped trie. +`concurrent.Map` is a trait in the Scala collections library. Currently, it has two implementations. The first one is Java's `java.util.concurrent.ConcurrentMap`, which can be converted automatically into a Scala map using the [standard Java/Scala collection conversions]({{ site.baseurl }}/overviews/collections/conversions-between-java-and-scala-collections.html). The second implementation is [TrieMap](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/concurrent/TrieMap.html), which is a lock-free implementation of a hash array mapped trie. ## Mutable Bitsets -A mutable bit of type [mutable.BitSet](http://www.scala-lang.org/api/{{ site.scala-213-version }}/scala/collection/mutable/BitSet.html) set is just like an immutable one, except that it is modified in place. Mutable bit sets are slightly more efficient at updating than immutable ones, because they don't have to copy around `Long`s that haven't changed. +A mutable bit of type [mutable.BitSet](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/mutable/BitSet.html) set is just like an immutable one, except that it is modified in place. Mutable bit sets are slightly more efficient at updating than immutable ones, because they don't have to copy around `Long`s that haven't changed. scala> val bits = scala.collection.mutable.BitSet.empty bits: scala.collection.mutable.BitSet = BitSet() diff --git a/_overviews/collections-2.13/iterators.md b/_overviews/collections-2.13/iterators.md index 55de58cb7e..6d71f2bd1b 100644 --- a/_overviews/collections-2.13/iterators.md +++ b/_overviews/collections-2.13/iterators.md @@ -12,7 +12,7 @@ num: 15 permalink: /overviews/collections-2.13/:title.html --- -An iterator is not a collection, but rather a way to access the elements of a collection one by one. The two basic operations on an iterator `it` are `next` and `hasNext`. A call to `it.next()` will return the next element of the iterator and advance the state of the iterator. Calling `next` again on the same iterator will then yield the element one beyond the one returned previously. If there are no more elements to return, a call to `next` will throw a `NoSuchElementException`. You can find out whether there are more elements to return using [Iterator](http://www.scala-lang.org/api/{{ site.scala-213-version }}/scala/collection/Iterator.html)'s `hasNext` method. +An iterator is not a collection, but rather a way to access the elements of a collection one by one. The two basic operations on an iterator `it` are `next` and `hasNext`. A call to `it.next()` will return the next element of the iterator and advance the state of the iterator. Calling `next` again on the same iterator will then yield the element one beyond the one returned previously. If there are no more elements to return, a call to `next` will throw a `NoSuchElementException`. You can find out whether there are more elements to return using [Iterator](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/Iterator.html)'s `hasNext` method. The most straightforward way to "step through" all the elements returned by an iterator `it` uses a while-loop: @@ -78,7 +78,7 @@ destructively modified by invoking arbitrary methods. This creates the illusion the elements twice, but the effect is achieved through internal buffering. As usual, the underlying iterator `it` cannot be used directly and must be discarded. -In summary, iterators behave like collections _if one never accesses an iterator again after invoking a method on it_. The Scala collection libraries make this explicit with an abstraction [IterableOnce](http://www.scala-lang.org/api/{{ site.scala-213-version }}/scala/collection/IterableOnce.html), which is a common superclass of [Iterable](http://www.scala-lang.org/api/{{ site.scala-213-version }}/scala/collection/Iterable.html) and [Iterator](http://www.scala-lang.org/api/{{ site.scala-213-version }}/scala/collection/Iterator.html). `IterableOnce[A]` only has two methods: `iterator: Iterator[A]` and `knownSize: Int`. If an `IterableOnce` object is in fact an `Iterator`, its `iterator` operation always returns itself, in its current state, but if it is an `Iterable`, its `iterator` operation always return a new `Iterator`. A common use case of `IterableOnce` is as an argument type for methods that can take either an iterator or a collection as argument. An example is the appending method `concat` in class `Iterable`. It takes an `IterableOnce` parameter, so you can append elements coming from either an iterator or a collection. +In summary, iterators behave like collections _if one never accesses an iterator again after invoking a method on it_. The Scala collection libraries make this explicit with an abstraction [IterableOnce](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/IterableOnce.html), which is a common superclass of [Iterable](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/Iterable.html) and [Iterator](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/Iterator.html). `IterableOnce[A]` only has two methods: `iterator: Iterator[A]` and `knownSize: Int`. If an `IterableOnce` object is in fact an `Iterator`, its `iterator` operation always returns itself, in its current state, but if it is an `Iterable`, its `iterator` operation always return a new `Iterator`. A common use case of `IterableOnce` is as an argument type for methods that can take either an iterator or a collection as argument. An example is the appending method `concat` in class `Iterable`. It takes an `IterableOnce` parameter, so you can append elements coming from either an iterator or a collection. All operations on iterators are summarized below. @@ -189,7 +189,7 @@ Sometimes you want an iterator that can "look ahead", so that you can inspect th 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! -The solution to this problem is to use a buffered iterator. Class [BufferedIterator](http://www.scala-lang.org/api/{{ site.scala-213-version }}/scala/collection/BufferedIterator.html) is a subclass of [Iterator](http://www.scala-lang.org/api/{{ site.scala-213-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. +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. def skipEmptyWords(it: BufferedIterator[String]) = while (it.head.isEmpty) { it.next() } diff --git a/_overviews/collections-2.13/overview.md b/_overviews/collections-2.13/overview.md index 79cb856cc3..a96995b662 100644 --- a/_overviews/collections-2.13/overview.md +++ b/_overviews/collections-2.13/overview.md @@ -40,10 +40,10 @@ mutable collection means you need to understand which code changes which collection when. A collection in package `scala.collection` can be either mutable or -immutable. For instance, [collection.IndexedSeq\[T\]](http://www.scala-lang.org/api/{{ site.scala-213-version }}/scala/collection/IndexedSeq.html) -is a superclass of both [collection.immutable.IndexedSeq\[T\]](http://www.scala-lang.org/api/{{ site.scala-213-version }}/scala/collection/immutable/IndexedSeq.html) +immutable. For instance, [collection.IndexedSeq\[T\]](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/IndexedSeq.html) +is a superclass of both [collection.immutable.IndexedSeq\[T\]](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/immutable/IndexedSeq.html) and -[collection.mutable.IndexedSeq\[T\]](http://www.scala-lang.org/api/{{ site.scala-213-version }}/scala/collection/mutable/IndexedSeq.html) +[collection.mutable.IndexedSeq\[T\]](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/mutable/IndexedSeq.html) Generally, the root collections in package `scala.collection` support transformation operations affecting the whole collection, the immutable @@ -92,7 +92,7 @@ can be accessed alternatively as // is always automatically imported Other types aliased are -[Iterable](http://www.scala-lang.org/api/{{ site.scala-213-version }}/scala/collection/Iterable.html), [Seq](http://www.scala-lang.org/api/{{ site.scala-213-version }}/scala/collection/immutable/Seq.html), [IndexedSeq](http://www.scala-lang.org/api/{{ site.scala-213-version }}/scala/collection/immutable/IndexedSeq.html), [Iterator](http://www.scala-lang.org/api/{{ site.scala-213-version }}/scala/collection/Iterator.html), [LazyList](http://www.scala-lang.org/api/{{ site.scala-213-version }}/scala/collection/immutable/LazyList.html), [Vector](http://www.scala-lang.org/api/{{ site.scala-213-version }}/scala/collection/immutable/Vector.html), [StringBuilder](http://www.scala-lang.org/api/{{ site.scala-213-version }}/scala/collection/mutable/StringBuilder.html), and [Range](http://www.scala-lang.org/api/{{ site.scala-213-version }}/scala/collection/immutable/Range.html). +[Iterable](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/Iterable.html), [Seq](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/immutable/Seq.html), [IndexedSeq](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/immutable/IndexedSeq.html), [Iterator](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/Iterator.html), [LazyList](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/immutable/LazyList.html), [Vector](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/immutable/Vector.html), [StringBuilder](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/mutable/StringBuilder.html), and [Range](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/immutable/Range.html). The following figure shows all collections in package `scala.collection`. These are all high-level abstract classes or traits, which diff --git a/_overviews/collections-2.13/trait-iterable.md b/_overviews/collections-2.13/trait-iterable.md index 3ae2ecfb99..e306f39f16 100644 --- a/_overviews/collections-2.13/trait-iterable.md +++ b/_overviews/collections-2.13/trait-iterable.md @@ -64,7 +64,7 @@ Two more methods exist in `Iterable` that return iterators: `grouped` and `slidi | `xs grouped size` |An iterator that yields fixed-sized "chunks" of this collection.| | `xs sliding size` |An iterator that yields a sliding fixed-sized window of elements in this collection.| | **Addition:** | | -| `xs concat ys`
(or `xs ++ ys`) |A collection consisting of the elements of both `xs` and `ys`. `ys` is a [IterableOnce](http://www.scala-lang.org/api/{{ site.scala-213-version }}/scala/collection/IterableOnce.html) collection, i.e., either an [Iterable](http://www.scala-lang.org/api/{{ site.scala-213-version }}/scala/collection/Iterable.html) or an [Iterator](http://www.scala-lang.org/api/{{ site.scala-213-version }}/scala/collection/Iterator.html).| +| `xs concat ys`
(or `xs ++ ys`) |A collection consisting of the elements of both `xs` and `ys`. `ys` is a [IterableOnce](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/IterableOnce.html) collection, i.e., either an [Iterable](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/Iterable.html) or an [Iterator](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/Iterator.html).| | **Maps:** | | | `xs map f` |The collection obtained from applying the function f to every element in `xs`.| | `xs flatMap f` |The collection obtained from applying the collection-valued function `f` to every element in `xs` and concatenating the results.| @@ -141,7 +141,7 @@ Two more methods exist in `Iterable` that return iterators: `grouped` and `slidi | **Views:** | | | `xs.view` |Produces a view over `xs`.| -In the inheritance hierarchy below `Iterable` you find three traits: [Seq](https://www.scala-lang.org/api/{{ site.scala-213-version }}/scala/collection/Seq.html), [Set](https://www.scala-lang.org/api/{{ site.scala-213-version }}/scala/collection/Set.html), and [Map](https://www.scala-lang.org/api/{{ site.scala-213-version }}/scala/collection/Map.html). `Seq` and `Map` implement the [PartialFunction](https://www.scala-lang.org/api/{{ site.scala-213-version }}/scala/PartialFunction.html) trait with its `apply` and `isDefinedAt` methods, each implemented differently. `Set` gets its `apply` method from [SetOps](https://www.scala-lang.org/api/{{ site.scala-213-version }}/scala/collection/SetOps.html). +In the inheritance hierarchy below `Iterable` you find three traits: [Seq](https://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/Seq.html), [Set](https://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/Set.html), and [Map](https://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/Map.html). `Seq` and `Map` implement the [PartialFunction](https://www.scala-lang.org/api/{{ site.scala-version }}/scala/PartialFunction.html) trait with its `apply` and `isDefinedAt` methods, each implemented differently. `Set` gets its `apply` method from [SetOps](https://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/SetOps.html). For sequences, `apply` is positional indexing, where elements are always numbered from `0`. That is, `Seq(1, 2, 3)(1)` gives `2`. For sets, `apply` is a membership test. For instance, `Set('a', 'b', 'c')('b')` gives `true` whereas `Set()('a')` gives `false`. Finally for maps, `apply` is a selection. For instance, `Map('a' -> 1, 'b' -> 10, 'c' -> 100)('b')` gives `10`. diff --git a/_overviews/collections/arrays.md b/_overviews/collections/arrays.md index 512df5e432..343ebb1c74 100644 --- a/_overviews/collections/arrays.md +++ b/_overviews/collections/arrays.md @@ -13,7 +13,7 @@ languages: [ja, zh-cn] permalink: /overviews/collections/:title.html --- -[Array](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/Array.html) is a special kind of collection in Scala. On the one hand, Scala arrays correspond one-to-one to Java arrays. That is, a Scala array `Array[Int]` is represented as a Java `int[]`, an `Array[Double]` is represented as a Java `double[]` and a `Array[String]` is represented as a Java `String[]`. But at the same time, Scala arrays offer much more than their Java analogues. First, Scala arrays can be _generic_. That is, you can have an `Array[T]`, where `T` is a type parameter or abstract type. Second, Scala arrays are compatible with Scala sequences - you can pass an `Array[T]` where a `Seq[T]` is required. Finally, Scala arrays also support all sequence operations. Here's an example of this in action: +[Array](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/Array.html) is a special kind of collection in Scala. On the one hand, Scala arrays correspond one-to-one to Java arrays. That is, a Scala array `Array[Int]` is represented as a Java `int[]`, an `Array[Double]` is represented as a Java `double[]` and a `Array[String]` is represented as a Java `String[]`. But at the same time, Scala arrays offer much more than their Java analogues. First, Scala arrays can be _generic_. That is, you can have an `Array[T]`, where `T` is a type parameter or abstract type. Second, Scala arrays are compatible with Scala sequences - you can pass an `Array[T]` where a `Seq[T]` is required. Finally, Scala arrays also support all sequence operations. Here's an example of this in action: scala> val a1 = Array(1, 2, 3) a1: Array[Int] = Array(1, 2, 3) diff --git a/_overviews/collections/concrete-immutable-collection-classes.md b/_overviews/collections/concrete-immutable-collection-classes.md index 64bfb62655..b0e16eceb7 100644 --- a/_overviews/collections/concrete-immutable-collection-classes.md +++ b/_overviews/collections/concrete-immutable-collection-classes.md @@ -17,7 +17,7 @@ Scala provides many concrete immutable collection classes for you to choose from ## Lists -A [List](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/immutable/List.html) is a finite immutable sequence. They provide constant-time access to their first element as well as the rest of the list, and they have a constant-time cons operation for adding a new element to the front of the list. Many other operations take linear time. +A [List](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/immutable/List.html) is a finite immutable sequence. They provide constant-time access to their first element as well as the rest of the list, and they have a constant-time cons operation for adding a new element to the front of the list. Many other operations take linear time. Lists have always been the workhorse for Scala programming, so not much needs to be said about them here. The major change in 2.8 is that the `List` class together with its subclass `::` and its subobject `Nil` is now defined in package `scala.collection.immutable`, where it logically belongs. There are still aliases for `List`, `Nil`, and `::` in the `scala` package, so from a user perspective, lists can be accessed as before. @@ -25,7 +25,7 @@ Another change is that lists now integrate more closely into the collections fra ## Streams -A [Stream](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/immutable/Stream.html) is like a list except that its elements are computed lazily. Because of this, a stream can be infinitely long. Only those elements requested are computed. Otherwise, streams have the same performance characteristics as lists. +A [Stream](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/immutable/Stream.html) is like a list except that its elements are computed lazily. Because of this, a stream can be infinitely long. Only those elements requested are computed. Otherwise, streams have the same performance characteristics as lists. Whereas lists are constructed with the `::` operator, streams are constructed with the similar-looking `#::`. Here is a simple example of a stream containing the integers 1, 2, and 3: @@ -52,7 +52,7 @@ Here are the first few elements of the Fibonacci sequence starting with two ones Lists are very efficient when the algorithm processing them is careful to only process their heads. Accessing, adding, and removing the head of a list takes only constant time, whereas accessing or modifying elements later in the list takes time linear in the depth into the list. -[Vector](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/immutable/Vector.html) is a collection type (introduced in Scala 2.8) that addresses the inefficiency for random access on lists. Vectors allow accessing any element of the list in "effectively" constant time. It's a larger constant than for access to the head of a list or for reading an element of an array, but it's a constant nonetheless. As a result, algorithms using vectors do not have to be careful about accessing just the head of the sequence. They can access and modify elements at arbitrary locations, and thus they can be much more convenient to write. +[Vector](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/immutable/Vector.html) is a collection type (introduced in Scala 2.8) that addresses the inefficiency for random access on lists. Vectors allow accessing any element of the list in "effectively" constant time. It's a larger constant than for access to the head of a list or for reading an element of an array, but it's a constant nonetheless. As a result, algorithms using vectors do not have to be careful about accessing just the head of the sequence. They can access and modify elements at arbitrary locations, and thus they can be much more convenient to write. Vectors are built and modified just like any other sequence. @@ -86,7 +86,7 @@ Because vectors strike a good balance between fast random selections and fast ra ## Immutable stacks -If you need a last-in-first-out sequence, you can use a [Stack](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/immutable/Stack.html). You push an element onto a stack with `push`, pop an element with `pop`, and peek at the top of the stack without removing it with `top`. All of these operations are constant time. +If you need a last-in-first-out sequence, you can use a [Stack](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/immutable/Stack.html). You push an element onto a stack with `push`, pop an element with `pop`, and peek at the top of the stack without removing it with `top`. All of these operations are constant time. Here are some simple operations performed on a stack: @@ -106,7 +106,7 @@ Immutable stacks are used rarely in Scala programs because their functionality i ## Immutable Queues -A [Queue](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/immutable/Queue.html) is just like a stack except that it is first-in-first-out rather than last-in-first-out. +A [Queue](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/immutable/Queue.html) is just like a stack except that it is first-in-first-out rather than last-in-first-out. Here's how you can create an empty immutable queue: @@ -134,7 +134,7 @@ Note that `dequeue` returns a pair consisting of the element removed and the res ## Ranges -A [Range](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/immutable/Range.html) is an ordered sequence of integers that are equally spaced apart. For example, "1, 2, 3," is a range, as is "5, 8, 11, 14." To create a range in Scala, use the predefined methods `to` and `by`. +A [Range](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/immutable/Range.html) is an ordered sequence of integers that are equally spaced apart. For example, "1, 2, 3," is a range, as is "5, 8, 11, 14." To create a range in Scala, use the predefined methods `to` and `by`. scala> 1 to 3 res2: scala.collection.immutable.Range.Inclusive = Range(1, 2, 3) @@ -150,7 +150,7 @@ Ranges are represented in constant space, because they can be defined by just th ## Hash Tries -Hash tries are a standard way to implement immutable sets and maps efficiently. They are supported by class [immutable.HashMap](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/immutable/HashMap.html). Their representation is similar to vectors in that they are also trees where every node has 32 elements or 32 subtrees. But the selection of these keys is now done based on hash code. For instance, to find a given key in a map, one first takes the hash code of the key. Then, the lowest 5 bits of the hash code are used to select the first subtree, followed by the next 5 bits and so on. The selection stops once all elements stored in a node have hash codes that differ from each other in the bits that are selected up to this level. +Hash tries are a standard way to implement immutable sets and maps efficiently. They are supported by class [immutable.HashMap](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/immutable/HashMap.html). Their representation is similar to vectors in that they are also trees where every node has 32 elements or 32 subtrees. But the selection of these keys is now done based on hash code. For instance, to find a given key in a map, one first takes the hash code of the key. Then, the lowest 5 bits of the hash code are used to select the first subtree, followed by the next 5 bits and so on. The selection stops once all elements stored in a node have hash codes that differ from each other in the bits that are selected up to this level. Hash tries strike a nice balance between reasonably fast lookups and reasonably efficient functional insertions (`+`) and deletions (`-`). That's why they underlie Scala's default implementations of immutable maps and sets. In fact, Scala has a further optimization for immutable sets and maps that contain less than five elements. Sets and maps with one to four elements are stored as single objects that just contain the elements (or key/value pairs in the case of a map) as fields. The empty immutable set and the empty immutable map is in each case a single object - there's no need to duplicate storage for those because an empty immutable set or map will always stay empty. @@ -158,7 +158,7 @@ Hash tries strike a nice balance between reasonably fast lookups and reasonably Red-black trees are a form of balanced binary tree where some nodes are designated "red" and others designated "black." Like any balanced binary tree, operations on them reliably complete in time logarithmic to the size of the tree. -Scala provides implementations of immutable sets and maps that use a red-black tree internally. Access them under the names [TreeSet](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/immutable/TreeSet.html) and [TreeMap](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/immutable/TreeMap.html). +Scala provides implementations of immutable sets and maps that use a red-black tree internally. Access them under the names [TreeSet](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/immutable/TreeSet.html) and [TreeMap](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/immutable/TreeMap.html). scala> scala.collection.immutable.TreeSet.empty[Int] @@ -170,7 +170,7 @@ Red-black trees are the standard implementation of `SortedSet` in Scala, because ## Immutable BitSets -A [BitSet](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/immutable/BitSet.html) represents a collection of small integers as the bits of a larger integer. For example, the bit set containing 3, 2, and 0 would be represented as the integer 1101 in binary, which is 13 in decimal. +A [BitSet](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/immutable/BitSet.html) represents a collection of small integers as the bits of a larger integer. For example, the bit set containing 3, 2, and 0 would be represented as the integer 1101 in binary, which is 13 in decimal. Internally, bit sets use an array of 64-bit `Long`s. The first `Long` in the array is for integers 0 through 63, the second is for 64 through 127, and so on. Thus, bit sets are very compact so long as the largest integer in the set is less than a few hundred or so. @@ -187,7 +187,7 @@ Operations on bit sets are very fast. Testing for inclusion takes constant time. ## List Maps -A [ListMap](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/immutable/ListMap.html) represents a map as a linked list of key-value pairs. In general, operations on a list map might have to iterate through the entire list. Thus, operations on a list map take time linear in the size of the map. In fact there is little usage for list maps in Scala because standard immutable maps are almost always faster. The only possible exception to this is if the map is for some reason constructed in such a way that the first elements in the list are selected much more often than the other elements. +A [ListMap](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/immutable/ListMap.html) represents a map as a linked list of key-value pairs. In general, operations on a list map might have to iterate through the entire list. Thus, operations on a list map take time linear in the size of the map. In fact there is little usage for list maps in Scala because standard immutable maps are almost always faster. The only possible exception to this is if the map is for some reason constructed in such a way that the first elements in the list are selected much more often than the other elements. scala> val map = scala.collection.immutable.ListMap(1->"one", 2->"two") map: scala.collection.immutable.ListMap[Int,java.lang.String] = diff --git a/_overviews/collections/concrete-mutable-collection-classes.md b/_overviews/collections/concrete-mutable-collection-classes.md index f229dc818d..432eb6df9f 100644 --- a/_overviews/collections/concrete-mutable-collection-classes.md +++ b/_overviews/collections/concrete-mutable-collection-classes.md @@ -17,7 +17,7 @@ You've now seen the most commonly used immutable collection classes that Scala p ## Array Buffers -An [ArrayBuffer](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/mutable/ArrayBuffer.html) buffer holds an array and a size. Most operations on an array buffer have the same speed as for an array, because the operations simply access and modify the underlying array. Additionally, array buffers can have data efficiently added to the end. Appending an item to an array buffer takes amortized constant time. Thus, array buffers are useful for efficiently building up a large collection whenever the new items are always added to the end. +An [ArrayBuffer](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/mutable/ArrayBuffer.html) buffer holds an array and a size. Most operations on an array buffer have the same speed as for an array, because the operations simply access and modify the underlying array. Additionally, array buffers can have data efficiently added to the end. Appending an item to an array buffer takes amortized constant time. Thus, array buffers are useful for efficiently building up a large collection whenever the new items are always added to the end. scala> val buf = scala.collection.mutable.ArrayBuffer.empty[Int] buf: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer() @@ -30,7 +30,7 @@ An [ArrayBuffer](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/co ## List Buffers -A [ListBuffer](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/mutable/ListBuffer.html) is like an array buffer except that it uses a linked list internally instead of an array. If you plan to convert the buffer to a list once it is built up, use a list buffer instead of an array buffer. +A [ListBuffer](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/mutable/ListBuffer.html) is like an array buffer except that it uses a linked list internally instead of an array. If you plan to convert the buffer to a list once it is built up, use a list buffer instead of an array buffer. scala> val buf = scala.collection.mutable.ListBuffer.empty[Int] buf: scala.collection.mutable.ListBuffer[Int] = ListBuffer() @@ -43,7 +43,7 @@ A [ListBuffer](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/coll ## StringBuilders -Just like an array buffer is useful for building arrays, and a list buffer is useful for building lists, a [StringBuilder](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/mutable/StringBuilder.html) is useful for building strings. String builders are so commonly used that they are already imported into the default namespace. Create them with a simple `new StringBuilder`, like this: +Just like an array buffer is useful for building arrays, and a list buffer is useful for building lists, a [StringBuilder](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/mutable/StringBuilder.html) is useful for building strings. String builders are so commonly used that they are already imported into the default namespace. Create them with a simple `new StringBuilder`, like this: scala> val buf = new StringBuilder buf: StringBuilder = @@ -56,15 +56,15 @@ Just like an array buffer is useful for building arrays, and a list buffer is us ## Linked Lists -Linked lists are mutable sequences that consist of nodes which are linked with next pointers. They are supported by class [LinkedList](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/mutable/LinkedList.html). In most languages `null` would be picked as the empty linked list. That does not work for Scala collections, because even empty sequences must support all sequence methods. In particular `LinkedList.empty.isEmpty` should return `true` and not throw a `NullPointerException`. Empty linked lists are encoded instead in a special way: Their `next` field points back to the node itself. Like their immutable cousins, linked lists are best traversed sequentially. In addition linked lists make it easy to insert an element or linked list into another linked list. +Linked lists are mutable sequences that consist of nodes which are linked with next pointers. They are supported by class [LinkedList](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/mutable/LinkedList.html). In most languages `null` would be picked as the empty linked list. That does not work for Scala collections, because even empty sequences must support all sequence methods. In particular `LinkedList.empty.isEmpty` should return `true` and not throw a `NullPointerException`. Empty linked lists are encoded instead in a special way: Their `next` field points back to the node itself. Like their immutable cousins, linked lists are best traversed sequentially. In addition linked lists make it easy to insert an element or linked list into another linked list. ## Double Linked Lists -Double linked lists are like single linked lists, except that they have besides `next` another mutable field `prev` that points to the element preceding the current node. The main benefit of that additional link is that it makes element removal very fast. Double linked lists are supported by class [DoubleLinkedList](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/mutable/DoubleLinkedList.html). +Double linked lists are like single linked lists, except that they have besides `next` another mutable field `prev` that points to the element preceding the current node. The main benefit of that additional link is that it makes element removal very fast. Double linked lists are supported by class [DoubleLinkedList](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/mutable/DoubleLinkedList.html). ## Mutable Lists -A [MutableList](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/mutable/MutableList.html) consists of a single linked list together with a pointer that refers to the terminal empty node of that list. This makes list append a constant time operation because it avoids having to traverse the list in search for its terminal node. [MutableList](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/mutable/MutableList.html) is currently the standard implementation of [mutable.LinearSeq](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/LinearSeq.html) in Scala. +A [MutableList](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/mutable/MutableList.html) consists of a single linked list together with a pointer that refers to the terminal empty node of that list. This makes list append a constant time operation because it avoids having to traverse the list in search for its terminal node. [MutableList](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/mutable/MutableList.html) is currently the standard implementation of [mutable.LinearSeq](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/LinearSeq.html) in Scala. ## Queues @@ -85,13 +85,13 @@ Scala provides mutable queues in addition to immutable ones. You use a `mQueue` ## Array Sequences -Array sequences are mutable sequences of fixed size which store their elements internally in an `Array[Object]`. They are implemented in Scala by class [ArraySeq](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/mutable/ArraySeq.html). +Array sequences are mutable sequences of fixed size which store their elements internally in an `Array[Object]`. They are implemented in Scala by class [ArraySeq](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/mutable/ArraySeq.html). You would typically use an `ArraySeq` if you want an array for its performance characteristics, but you also want to create generic instances of the sequence where you do not know the type of the elements and you do not have a `ClassTag` to provide it at run-time. These issues are explained in the section on [arrays]({{ site.baseurl }}/overviews/collections/arrays.html). ## Stacks -You saw immutable stacks earlier. There is also a mutable version, supported by class [mutable.Stack](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/mutable/Stack.html). It works exactly the same as the immutable version except that modifications happen in place. +You saw immutable stacks earlier. There is also a mutable version, supported by class [mutable.Stack](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/mutable/Stack.html). It works exactly the same as the immutable version except that modifications happen in place. scala> val stack = new scala.collection.mutable.Stack[Int] stack: scala.collection.mutable.Stack[Int] = Stack() @@ -114,11 +114,11 @@ You saw immutable stacks earlier. There is also a mutable version, supported by ## Array Stacks -[ArrayStack](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/mutable/ArrayStack.html) is an alternative implementation of a mutable stack which is backed by an Array that gets re-sized as needed. It provides fast indexing and is generally slightly more efficient for most operations than a normal mutable stack. +[ArrayStack](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/mutable/ArrayStack.html) is an alternative implementation of a mutable stack which is backed by an Array that gets re-sized as needed. It provides fast indexing and is generally slightly more efficient for most operations than a normal mutable stack. ## Hash Tables -A hash table stores its elements in an underlying array, placing each item at a position in the array determined by the hash code of that item. Adding an element to a hash table takes only constant time, so long as there isn't already another element in the array that has the same hash code. Hash tables are thus very fast so long as the objects placed in them have a good distribution of hash codes. As a result, the default mutable map and set types in Scala are based on hash tables. You can access them also directly under the names [mutable.HashSet](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/mutable/HashSet.html) and [mutable.HashMap](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/mutable/HashMap.html). +A hash table stores its elements in an underlying array, placing each item at a position in the array determined by the hash code of that item. Adding an element to a hash table takes only constant time, so long as there isn't already another element in the array that has the same hash code. Hash tables are thus very fast so long as the objects placed in them have a good distribution of hash codes. As a result, the default mutable map and set types in Scala are based on hash tables. You can access them also directly under the names [mutable.HashSet](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/mutable/HashSet.html) and [mutable.HashMap](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/mutable/HashMap.html). Hash sets and maps are used just like any other set or map. Here are some simple examples: @@ -137,11 +137,11 @@ Iteration over a hash table is not guaranteed to occur in any particular order. ## Weak Hash Maps -A weak hash map is a special kind of hash map where the garbage collector does not follow links from the map to the keys stored in it. This means that a key and its associated value will disappear from the map if there is no other reference to that key. Weak hash maps are useful for tasks such as caching, where you want to re-use an expensive function's result if the function is called again on the same key. If keys and function results are stored in a regular hash map, the map could grow without bounds, and no key would ever become garbage. Using a weak hash map avoids this problem. As soon as a key object becomes unreachable, it's entry is removed from the weak hashmap. Weak hash maps in Scala are implemented by class [WeakHashMap](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/mutable/WeakHashMap.html) as a wrapper of an underlying Java implementation `java.util.WeakHashMap`. +A weak hash map is a special kind of hash map where the garbage collector does not follow links from the map to the keys stored in it. This means that a key and its associated value will disappear from the map if there is no other reference to that key. Weak hash maps are useful for tasks such as caching, where you want to re-use an expensive function's result if the function is called again on the same key. If keys and function results are stored in a regular hash map, the map could grow without bounds, and no key would ever become garbage. Using a weak hash map avoids this problem. As soon as a key object becomes unreachable, it's entry is removed from the weak hashmap. Weak hash maps in Scala are implemented by class [WeakHashMap](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/mutable/WeakHashMap.html) as a wrapper of an underlying Java implementation `java.util.WeakHashMap`. ## Concurrent Maps -A concurrent map can be accessed by several threads at once. In addition to the usual [Map](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/Map.html) operations, it provides the following atomic operations: +A concurrent map can be accessed by several threads at once. In addition to the usual [Map](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/Map.html) operations, it provides the following atomic operations: ### Operations in class ConcurrentMap @@ -156,7 +156,7 @@ A concurrent map can be accessed by several threads at once. In addition to the ## Mutable Bitsets -A mutable bit of type [mutable.BitSet](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/mutable/BitSet.html) set is just like an immutable one, except that it is modified in place. Mutable bit sets are slightly more efficient at updating than immutable ones, because they don't have to copy around `Long`s that haven't changed. +A mutable bit of type [mutable.BitSet](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/mutable/BitSet.html) set is just like an immutable one, except that it is modified in place. Mutable bit sets are slightly more efficient at updating than immutable ones, because they don't have to copy around `Long`s that haven't changed. scala> val bits = scala.collection.mutable.BitSet.empty bits: scala.collection.mutable.BitSet = BitSet() diff --git a/_overviews/collections/conversions-between-java-and-scala-collections.md b/_overviews/collections/conversions-between-java-and-scala-collections.md index c476d4369c..7d1f3d150a 100644 --- a/_overviews/collections/conversions-between-java-and-scala-collections.md +++ b/_overviews/collections/conversions-between-java-and-scala-collections.md @@ -15,7 +15,7 @@ permalink: /overviews/collections/:title.html Like Scala, Java also has a rich collections library. There are many similarities between the two. For instance, both libraries know iterators, iterables, sets, maps, and sequences. But there are also important differences. In particular, the Scala libraries put much more emphasis on immutable collections, and provide many more operations that transform a collection into a new one. -Sometimes you might need to pass from one collection framework to the other. For instance, you might want to access an existing Java collection as if it were a Scala collection. Or you might want to pass one of Scala's collections to a Java method that expects its Java counterpart. It is quite easy to do this, because Scala offers implicit conversions between all the major collection types in the [JavaConverters](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/JavaConverters$.html) object. In particular, you will find bidirectional conversions between the following types. +Sometimes you might need to pass from one collection framework to the other. For instance, you might want to access an existing Java collection as if it were a Scala collection. Or you might want to pass one of Scala's collections to a Java method that expects its Java counterpart. It is quite easy to do this, because Scala offers implicit conversions between all the major collection types in the [JavaConverters](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/JavaConverters$.html) object. In particular, you will find bidirectional conversions between the following types. Iterator <=> java.util.Iterator @@ -27,7 +27,7 @@ Sometimes you might need to pass from one collection framework to the other. For mutable.Map <=> java.util.Map mutable.ConcurrentMap <=> java.util.concurrent.ConcurrentMap -To enable these conversions, simply import them from the [JavaConverters](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/JavaConverters$.html) object: +To enable these conversions, simply import them from the [JavaConverters](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/JavaConverters$.html) object: scala> import collection.JavaConverters._ import collection.JavaConverters._ diff --git a/_overviews/collections/iterators.md b/_overviews/collections/iterators.md index e771513c0c..975824d498 100644 --- a/_overviews/collections/iterators.md +++ b/_overviews/collections/iterators.md @@ -13,7 +13,7 @@ languages: [ja, zh-cn] permalink: /overviews/collections/:title.html --- -An iterator is not a collection, but rather a way to access the elements of a collection one by one. The two basic operations on an iterator `it` are `next` and `hasNext`. A call to `it.next()` will return the next element of the iterator and advance the state of the iterator. Calling `next` again on the same iterator will then yield the element one beyond the one returned previously. If there are no more elements to return, a call to `next` will throw a `NoSuchElementException`. You can find out whether there are more elements to return using [Iterator](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/Iterator.html)'s `hasNext` method. +An iterator is not a collection, but rather a way to access the elements of a collection one by one. The two basic operations on an iterator `it` are `next` and `hasNext`. A call to `it.next()` will return the next element of the iterator and advance the state of the iterator. Calling `next` again on the same iterator will then yield the element one beyond the one returned previously. If there are no more elements to return, a call to `next` will throw a `NoSuchElementException`. You can find out whether there are more elements to return using [Iterator](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/Iterator.html)'s `hasNext` method. The most straightforward way to "step through" all the elements returned by an iterator `it` uses a while-loop: @@ -76,7 +76,7 @@ destructively modified by invoking arbitrary methods. This creates the illusion the elements twice, but the effect is achieved through internal buffering. As usual, the underlying iterator `it` cannot be used directly and must be discarded. -In summary, iterators behave like collections _if one never accesses an iterator again after invoking a method on it_. The Scala collection libraries make this explicit with an abstraction [TraversableOnce](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/TraversableOnce.html), which is a common superclass of [Traversable](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/Traversable.html) and [Iterator](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/Iterator.html). As the name implies, `TraversableOnce` objects can be traversed using `foreach` but the state of that object after the traversal is not specified. If the `TraversableOnce` object is in fact an `Iterator`, it will be at its end after the traversal, but if it is a `Traversable`, it will still exist as before. A common use case of `TraversableOnce` is as an argument type for methods that can take either an iterator or a traversable as argument. An example is the appending method `++` in class `Traversable`. It takes a `TraversableOnce` parameter, so you can append elements coming from either an iterator or a traversable collection. +In summary, iterators behave like collections _if one never accesses an iterator again after invoking a method on it_. The Scala collection libraries make this explicit with an abstraction [TraversableOnce](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/TraversableOnce.html), which is a common superclass of [Traversable](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/Traversable.html) and [Iterator](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/Iterator.html). As the name implies, `TraversableOnce` objects can be traversed using `foreach` but the state of that object after the traversal is not specified. If the `TraversableOnce` object is in fact an `Iterator`, it will be at its end after the traversal, but if it is a `Traversable`, it will still exist as before. A common use case of `TraversableOnce` is as an argument type for methods that can take either an iterator or a traversable as argument. An example is the appending method `++` in class `Traversable`. It takes a `TraversableOnce` parameter, so you can append elements coming from either an iterator or a traversable collection. All operations on iterators are summarized below. @@ -186,7 +186,7 @@ Sometimes you want an iterator that can "look ahead", so that you can inspect th 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! -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. +The solution to this problem is to use a buffered iterator. Class [BufferedIterator](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/BufferedIterator.html) is a subclass of [Iterator](http://www.scala-lang.org/api/{{ site.scala-212-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. def skipEmptyWords(it: BufferedIterator[String]) = while (it.head.isEmpty) { it.next() } diff --git a/_overviews/parallel-collections/concrete-parallel-collections.md b/_overviews/parallel-collections/concrete-parallel-collections.md index d171a4968a..3c82e34930 100644 --- a/_overviews/parallel-collections/concrete-parallel-collections.md +++ b/_overviews/parallel-collections/concrete-parallel-collections.md @@ -15,7 +15,7 @@ permalink: /overviews/parallel-collections/:title.html ## Parallel Array -A [ParArray](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/parallel/mutable/ParArray.html) +A [ParArray](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/parallel/mutable/ParArray.html) sequence holds a linear, contiguous array of elements. This means that the elements can be accessed and updated efficiently by modifying the underlying array. Traversing the @@ -54,7 +54,7 @@ parallel array it was obtained from. ## Parallel Vector -A [ParVector](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/parallel/immutable/ParVector.html) +A [ParVector](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/parallel/immutable/ParVector.html) is an immutable sequence with a low-constant factor logarithmic access and update time. @@ -76,16 +76,16 @@ combiners will be combined using concatenation and transformer methods will become much more efficient. Parallel vector is a parallel counterpart of the sequential -[Vector](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/immutable/Vector.html), +[Vector](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/immutable/Vector.html), so conversion between the two takes constant time. ## Parallel Range -A [ParRange](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/parallel/immutable/ParRange.html) +A [ParRange](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/parallel/immutable/ParRange.html) is an ordered sequence of elements equally spaced apart. A parallel range is created in a similar way as the sequential -[Range](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/immutable/Range.html): +[Range](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/immutable/Range.html): scala> 1 to 3 par res0: scala.collection.parallel.immutable.ParRange = ParRange(1, 2, 3) @@ -105,9 +105,9 @@ another using the `seq` and `par` methods. Parallel hash tables store their elements in an underlying array and place them in the position determined by the hash code of the respective element. Parallel mutable hash sets -([mutable.ParHashSet](http://www.scala-lang.org/api/{{ site.scala-version}}/scala/collection/parallel/mutable/ParHashSet.html)) +([mutable.ParHashSet](http://www.scala-lang.org/api/{{ site.scala-212-version}}/scala/collection/parallel/mutable/ParHashSet.html)) and parallel mutable hash maps -([mutable.ParHashMap](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/parallel/mutable/ParHashMap.html)) +([mutable.ParHashMap](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/parallel/mutable/ParHashMap.html)) are based on hash tables. scala> val phs = scala.collection.parallel.mutable.ParHashSet(1 until 2000: _*) @@ -142,9 +142,9 @@ versa. Parallel hash tries are a parallel counterpart of the immutable hash tries, which are used to represent immutable sets and maps efficiently. They are supported by classes -[immutable.ParHashSet](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/parallel/immutable/ParHashSet.html) +[immutable.ParHashSet](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/parallel/immutable/ParHashSet.html) and -[immutable.ParHashMap](http://www.scala-lang.org/api/{{ site.scala-version}}/scala/collection/parallel/immutable/ParHashMap.html). +[immutable.ParHashMap](http://www.scala-lang.org/api/{{ site.scala-212-version}}/scala/collection/parallel/immutable/ParHashMap.html). scala> val phs = scala.collection.parallel.immutable.ParHashSet(1 until 1000: _*) phs: scala.collection.parallel.immutable.ParHashSet[Int] = ParSet(645, 892, 69, 809, 629, 365, 138, 760, 101, 479,... @@ -165,9 +165,9 @@ by using the `seq` and `par` method in constant time. ## Parallel Concurrent Tries -A [concurrent.TrieMap](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/concurrent/TrieMap.html) +A [concurrent.TrieMap](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/concurrent/TrieMap.html) is a concurrent thread-safe map, whereas a -[mutable.ParTrieMap](http://www.scala-lang.org/api/{{ site.scala-version}}/scala/collection/parallel/mutable/ParTrieMap.html) +[mutable.ParTrieMap](http://www.scala-lang.org/api/{{ site.scala-212-version}}/scala/collection/parallel/mutable/ParTrieMap.html) is its parallel counterpart. While most concurrent data structures do not guarantee consistent traversal if the data structure is modified during traversal, Ctries guarantee that updates are only visible in the next iteration. This diff --git a/api/all.md b/api/all.md index 77ecd28618..7c655d88d0 100644 --- a/api/all.md +++ b/api/all.md @@ -6,6 +6,10 @@ includeTOC: true ## Latest releases +* Scala 2.13.0 + * [Library API](https://www.scala-lang.org/api/2.13.0/) + * [Compiler API](https://www.scala-lang.org/api/2.13.0/scala-compiler/scala/) + * [Reflection API](https://www.scala-lang.org/api/2.13.0/scala-reflect/scala/reflect/) * Scala 2.12.8 * [Library API](https://www.scala-lang.org/api/2.12.8/) * [Compiler API](https://www.scala-lang.org/api/2.12.8/scala-compiler/scala/) @@ -26,12 +30,14 @@ includeTOC: true * [Continuations API](https://www.scala-lang.org/files/archive/api/2.11.12/scala-continuations-library/#scala.util.continuations.package) * [Scala 2.10.7](https://www.scala-lang.org/api/2.10.7/) + ## Nightly builds