Как использовать изменяемые коллекции в 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)

Такое поведение не кажется отдельным от неизменных коллекций, так когда же они ведут себя отдельно?

4 ответа

Решение

Для неизменяемых и изменяемых коллекций, :+ а также +: создавать новые коллекции. Если вы хотите, чтобы изменяемые коллекции автоматически увеличивались, используйте += а также +=: методы, определенные collection.mutable.Buffer,

Так же, map возвращает новую коллекцию - ищите transform изменить коллекцию на месте.

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)

Как отмечают другие, mapи методы возвращают измененную копию коллекции. В более общем смысле все методы, определенные в коллекциях из scala.collectionпакет никогда не изменит коллекцию на месте, даже если динамический тип коллекции из scala.collection.mutable. Чтобы изменить коллекцию на месте, найдите методы, определенные в scala.collection.mutable._но не в scala.collection._.

Например, :+определен в , поэтому он никогда не будет выполнять модификацию на месте, даже если динамический тип — это . Однако, +=, который определен в scala.collection.mutable.ArrayBufferи не в scala.collection.Seq, изменит коллекцию на месте.

map Метод никогда не изменяет коллекцию, в которой вы его вызываете. Система типов не позволит такой реализации карты на месте существовать - если только вы не изменили сигнатуру типа, так что для некоторого типа Collection[A] Вы могли только отобразить, используя функцию типа A => A,

(Редактировать: как уже указывалось в других ответах, существует такой метод, который называется transform!)

Так как map создает новую коллекцию, вы можете перейти от Collection[A] к Collection[B] используя функцию A => B, что гораздо полезнее.

Другие вопросы по тегам