Как использовать измененные коллекции в Scala
Я думаю, что я не понимаю, как работают изменчивые коллекции. Я ожидал бы, что изменчивые коллекции будут затронуты, применив к ним карту или добавив новые элементы:
scala> val s: collection.mutable.Seq[Int] = collection.mutable.Seq(1)
s: scala.collection.mutable.Seq[Int] = ArrayBuffer(1)
scala> s :+ 2 //appended an element
res32: scala.collection.mutable.Seq[Int] = ArrayBuffer(1, 2)
scala> s //the original collection is unchanged
res33: scala.collection.mutable.Seq[Int] = ArrayBuffer(1)
scala> s.map(_.toString) //mapped a function to it
res34: scala.collection.mutable.Seq[java.lang.String] = ArrayBuffer(1)
scala> s //original is unchanged
res35: scala.collection.mutable.Seq[Int] = ArrayBuffer(1)
//maybe mapping a function that changes the type of the collection shouldn't work
//try Int => Int
scala> s.map(_ + 1)
res36: scala.collection.mutable.Seq[Int] = ArrayBuffer(2)
scala> s //original unchanged
res37: scala.collection.mutable.Seq[Int] = ArrayBuffer(1)
Такое поведение не кажется отдельным от неизменяемых коллекций, поэтому, когда они ведут себя отдельно?
Ответы
Ответ 1
Для неизменяемых и изменяемых коллекций :+
и +:
создавать новые коллекции. Если вы хотите, чтобы изменяемые коллекции автоматически увеличивались, используйте методы +=
и +=:
определенные collection.mutable.Buffer
.
Аналогично, map
возвращает новую коллекцию - ищите transform
чтобы изменить коллекцию на месте.
Ответ 2
Операция map
применяет данную функцию ко всем элементам коллекции, а создает новую коллекцию.
Операция, которую вы ищете, называется transform
. Вы можете думать об этом как о месте map
, за исключением того, что функция преобразования должна быть типа a -> a
вместо a -> b
.
scala> import collection.mutable.Buffer
import collection.mutable.Buffer
scala> Buffer(6, 3, 90)
res1: scala.collection.mutable.Buffer[Int] = ArrayBuffer(6, 3, 90)
scala> res1 transform { 2 * }
res2: res1.type = ArrayBuffer(12, 6, 180)
scala> res1
res3: scala.collection.mutable.Buffer[Int] = ArrayBuffer(12, 6, 180)
Ответ 3
Метод map
никогда не изменяет коллекцию, на которую вы ее называете. Система типов не позволит реализовать такую реализацию на месте - если вы не изменили ее сигнатуру типа, так что на каком-то типе Collection[A]
вы могли бы отображать только функцию типа A => A
.
(Edit: как указывали другие ответы, существует такой метод, называемый transform
!)
Поскольку map
создает новую коллекцию, вы можете перейти от Collection[A]
к Collection[B]
с помощью функции A => B
, что гораздо более полезно.