0
# ArraySeq Implementation
1
2
This document covers the `ArraySeq` collection type, an immutable array-backed sequence with efficient indexed access.
3
4
## ArraySeq Abstract Class
5
6
### Core Interface
7
8
```scala { .api }
9
abstract class ArraySeq[+T] extends AbstractSeq[T] with IndexedSeq[T] {
10
/**
11
* The tag of the element type, used for array operations.
12
*/
13
protected def elemTag: ClassTag[T]
14
15
/**
16
* The length of the underlying array.
17
*/
18
def length: Int
19
20
/**
21
* Access element at the given index with efficient O(1) access.
22
*/
23
def apply(index: Int): T
24
25
/**
26
* Access to the underlying array. Use with caution as mutations
27
* will affect the ArraySeq's immutability guarantees.
28
*/
29
def unsafeArray: Array[T @uncheckedVariance]
30
31
/**
32
* Creates a new builder for this collection type.
33
*/
34
override protected def newBuilder: Builder[T, ArraySeq[T]]
35
36
/**
37
* Clones this ArraySeq, including a copy of the underlying array.
38
*/
39
override def clone(): ArraySeq[T]
40
}
41
```
42
43
## ArraySeq Companion Object
44
45
### Factory Methods
46
47
```scala { .api }
48
object ArraySeq {
49
/**
50
* Creates an empty ArraySeq for reference types.
51
*/
52
def empty[T <: AnyRef]: ArraySeq[T]
53
54
/**
55
* Wraps an existing array into an ArraySeq without copying.
56
* The array should not be mutated after wrapping to maintain immutability.
57
*/
58
def unsafeWrapArray[T](x: Array[T]): ArraySeq[T]
59
60
/**
61
* Implicit CanBuildFrom for creating ArraySeq instances.
62
*/
63
implicit def canBuildFrom[T: ClassTag]: CanBuildFrom[ArraySeq[_], T, ArraySeq[T]]
64
}
65
```
66
67
## Primitive Specializations
68
69
ArraySeq provides optimized implementations for all primitive types to avoid boxing overhead.
70
71
### Reference Type Specialization
72
73
```scala { .api }
74
final class ofRef[T <: AnyRef](val unsafeArray: Array[T])
75
extends ArraySeq[T] with Serializable {
76
77
lazy val elemTag: ClassTag[T]
78
def length: Int
79
def apply(index: Int): T
80
override def hashCode: Int
81
override def equals(that: Any): Boolean
82
}
83
```
84
85
### Numeric Primitive Specializations
86
87
```scala { .api }
88
// Byte specialization
89
final class ofByte(val unsafeArray: Array[Byte])
90
extends ArraySeq[Byte] with Serializable {
91
def elemTag: ClassTag[Byte]
92
def length: Int
93
def apply(index: Int): Byte
94
override def hashCode: Int
95
override def equals(that: Any): Boolean
96
}
97
98
// Short specialization
99
final class ofShort(val unsafeArray: Array[Short])
100
extends ArraySeq[Short] with Serializable {
101
def elemTag: ClassTag[Short]
102
def length: Int
103
def apply(index: Int): Short
104
override def hashCode: Int
105
override def equals(that: Any): Boolean
106
}
107
108
// Int specialization
109
final class ofInt(val unsafeArray: Array[Int])
110
extends ArraySeq[Int] with Serializable {
111
def elemTag: ClassTag[Int]
112
def length: Int
113
def apply(index: Int): Int
114
override def hashCode: Int
115
override def equals(that: Any): Boolean
116
}
117
118
// Long specialization
119
final class ofLong(val unsafeArray: Array[Long])
120
extends ArraySeq[Long] with Serializable {
121
def elemTag: ClassTag[Long]
122
def length: Int
123
def apply(index: Int): Long
124
override def hashCode: Int
125
override def equals(that: Any): Boolean
126
}
127
128
// Float specialization
129
final class ofFloat(val unsafeArray: Array[Float])
130
extends ArraySeq[Float] with Serializable {
131
def elemTag: ClassTag[Float]
132
def length: Int
133
def apply(index: Int): Float
134
override def hashCode: Int
135
override def equals(that: Any): Boolean
136
}
137
138
// Double specialization
139
final class ofDouble(val unsafeArray: Array[Double])
140
extends ArraySeq[Double] with Serializable {
141
def elemTag: ClassTag[Double]
142
def length: Int
143
def apply(index: Int): Double
144
override def hashCode: Int
145
override def equals(that: Any): Boolean
146
}
147
```
148
149
### Other Primitive Specializations
150
151
```scala { .api }
152
// Char specialization
153
final class ofChar(val unsafeArray: Array[Char])
154
extends ArraySeq[Char] with Serializable {
155
def elemTag: ClassTag[Char]
156
def length: Int
157
def apply(index: Int): Char
158
override def hashCode: Int
159
override def equals(that: Any): Boolean
160
}
161
162
// Boolean specialization
163
final class ofBoolean(val unsafeArray: Array[Boolean])
164
extends ArraySeq[Boolean] with Serializable {
165
def elemTag: ClassTag[Boolean]
166
def length: Int
167
def apply(index: Int): Boolean
168
override def hashCode: Int
169
override def equals(that: Any): Boolean
170
}
171
172
// Unit specialization
173
final class ofUnit(val unsafeArray: Array[Unit])
174
extends ArraySeq[Unit] with Serializable {
175
def elemTag: ClassTag[Unit]
176
def length: Int
177
def apply(index: Int): Unit
178
override def hashCode: Int
179
override def equals(that: Any): Boolean
180
}
181
```
182
183
## Usage Examples
184
185
### Basic ArraySeq Creation
186
187
```scala
188
import scala.collection.compat.immutable.ArraySeq
189
190
// Create from elements
191
val seq1 = ArraySeq(1, 2, 3, 4, 5)
192
println(seq1(2)) // 3
193
194
// Create empty
195
val empty = ArraySeq.empty[String]
196
197
// Efficient indexed access
198
val element = seq1(3) // O(1) access, returns 4
199
```
200
201
### Wrapping Existing Arrays
202
203
```scala
204
import scala.collection.compat.immutable.ArraySeq
205
206
// Wrap existing array without copying
207
val array = Array("hello", "world", "scala")
208
val arraySeq = ArraySeq.unsafeWrapArray(array)
209
210
// Access elements
211
println(arraySeq(0)) // "hello"
212
println(arraySeq.length) // 3
213
214
// Note: Don't mutate the original array after wrapping
215
// array(0) = "modified" // This would break immutability!
216
```
217
218
### Primitive Type Usage
219
220
```scala
221
import scala.collection.compat.immutable.ArraySeq
222
223
// Specialized for primitives - no boxing overhead
224
val intSeq = ArraySeq(1, 2, 3, 4, 5) // ArraySeq.ofInt
225
val doubleSeq = ArraySeq(1.0, 2.0, 3.0) // ArraySeq.ofDouble
226
val boolSeq = ArraySeq(true, false, true) // ArraySeq.ofBoolean
227
228
// Direct array access (use with caution)
229
val intArray: Array[Int] = intSeq.unsafeArray
230
```
231
232
### Builder Pattern
233
234
```scala
235
import scala.collection.compat.immutable.ArraySeq
236
import scala.collection.mutable.ArrayBuilder
237
238
// Using the companion object's builder
239
val builder = ArraySeq.canBuildFrom[String].apply()
240
builder += "first"
241
builder += "second"
242
builder ++= List("third", "fourth")
243
val result = builder.result()
244
245
// Or using a specific array builder
246
implicit val tag = scala.reflect.ClassTag.Int
247
val intBuilder = ArrayBuilder.make[Int]()
248
intBuilder ++= (1 to 10)
249
val intSeq = ArraySeq.unsafeWrapArray(intBuilder.result())
250
```
251
252
### Cloning and Equality
253
254
```scala
255
import scala.collection.compat.immutable.ArraySeq
256
257
val original = ArraySeq(1, 2, 3, 4, 5)
258
259
// Clone creates a copy of the underlying array
260
val cloned = original.clone()
261
println(original == cloned) // true (same elements)
262
println(original eq cloned) // false (different objects)
263
264
// Structural equality
265
val same = ArraySeq(1, 2, 3, 4, 5)
266
println(original == same) // true
267
268
// Hash codes are consistent
269
println(original.hashCode == same.hashCode) // true
270
```
271
272
### Performance Characteristics
273
274
```scala
275
import scala.collection.compat.immutable.ArraySeq
276
277
val large = ArraySeq((1 to 1000000): _*)
278
279
// O(1) random access
280
val element = large(500000)
281
282
// O(1) length
283
val size = large.length
284
285
// Memory efficient - backed by primitive array for specialized types
286
val memory = large.unsafeArray // Direct array access
287
```
288
289
### Working with Generic Code
290
291
```scala
292
import scala.collection.compat.immutable.ArraySeq
293
import scala.collection.compat._
294
295
def processSeq[T](seq: IndexedSeq[T]): T = {
296
// ArraySeq implements IndexedSeq efficiently
297
seq(seq.length / 2)
298
}
299
300
val stringSeq = ArraySeq("a", "b", "c", "d", "e")
301
val middle = processSeq(stringSeq) // "c"
302
303
// Converting to other collections
304
val list = stringSeq.to(List)
305
val vector = stringSeq.to(Vector)
306
val set = stringSeq.to(Set)
307
```
308
309
## Cross-Version Compatibility
310
311
In Scala 2.13, `scala.collection.compat.immutable.ArraySeq` is an alias for `scala.collection.immutable.ArraySeq`. In Scala 2.11/2.12, it's a complete implementation providing the same API.
312
313
This ensures that code using ArraySeq works identically across all supported Scala versions, with the same performance characteristics and primitive specializations.