Предположим, у нас есть пользовательская коллекция
class CopyOnWriteCollection<T> {
// returns copy of collection with new element
fun add(element: T): CopyOnWriteCollection<T> {
...
}
}
если мне нужно добавить несколько элементов, я бы сделал что-то вроде этого:
val newCollection = oldCollection
.add(1)
.add(2)
.add(3)
А newCollection содержит элементы из oldCollection, а также содержит 1,2,3.
Идеально!
Но как я могу добавить элементы из другой коллекции, используя forEach из map?
val collection = CopyOnWriteCollection()
(1..3).forEach { collection.add(it) } // this approach works only with mutable collections





Вы можете использовать императивный цикл или функцию fold():
fun main() {
var collection = CopyOnWriteCollection<Int>()
var collection2 = collection
for (i in 1..3) {
collection = collection.add(i)
}
println(collection)
collection2 = (1..3).fold(collection2) { coll, i -> coll.add(i) }
println(collection2)
}
class CopyOnWriteCollection<T> {
private val list = mutableListOf<T>()
// returns copy of collection with new element
fun add(element: T): CopyOnWriteCollection<T> {
val copy = CopyOnWriteCollection<T>()
copy.list.addAll(this.list)
copy.list.add(element)
return copy;
}
override fun toString() = list.toString()
}
Если класс CopyOnWriteCollection находится под вашим контролем, я бы подошел к этому, добавив к нему метод addAll():
/** Returns copy of collection with new element. */
fun addAll(elements: Collection<T>): CopyOnWriteCollection<T> {
// ...
}
Затем вы можете назвать это, например.
val newCollection = oldCollection.addAll(listOf(1, 2, 3))
(Или вы могли бы взять vararg вместо коллекции.)
Вероятно, это займет намного меньше времени и памяти.
(Кроме того, если вам действительно нужно написать свой собственный класс коллекции, я настоятельно рекомендую реализовать Collection (или один из его подынтерфейсов, если это необходимо) или расширить класс, который делает это. Это даст доступ к огромному диапазону методов расширения и другие вкусности в stdlib.)