scala:集合对象可变吗?



这个问题没有功能价值。只是想更好地理解scala。所有集合固有的Iterable。Iterable中没有isMutable方法。征求关于以下isMutable是否最有效地评估可变性的意见。这似乎过时了,但除了测试所有可变集合类之外,找不到其他替代方法,这并不理想,因为将来可能会添加新的可变类。(我将使用implicit定义方法,但为了简单起见没有这样做)。

import scala.collection.{immutable, mutable}
object IsMutable extends App {
val mutableMap: mutable.Map[String, Int] = mutable.Map("Apples" -> 4,"Pineapples" -> 1,"Oranges" -> 10,"Grapes" -> 7)
val immutableMap: immutable.Map[String, Int] = Map("Apples" -> 4,"Pineapples" -> 1,"Oranges" -> 10,"Grapes" -> 7)
def isMutable[A](obj: Iterable[A]): Boolean = obj.getClass.toString.startsWith("class scala.collection.mutable")
println(isMutable(mutableMap))
println(isMutable(immutableMap))
}

我认为依赖于类名不是一个好方法,尽管我相信,我提出的方法可能不是最优雅/最好的方法来找出一个集合是否可变。但是你可以使用这个:

import scala.reflect.ClassTag
def isMutable[T](iterable: scala.collection.Iterable[T]): Boolean = 
iterable.isInstanceOf[scala.collection.mutable.Iterable[T]]

我认为它对大多数类型都可以很好地工作(下面奇怪的界面是因为我使用菊石作为REPL,这很酷:D)。

@ val immutableMap = scala.collection.immutable.Map[String, String]() 
immutableMap: Map[String, String] = Map()
@ isMutable(immutableMap) 
res14: Boolean = false
@ val mutableMap = scala.collection.mutable.Map[String, String]() 
mutableMap: mutable.Map[String, String] = HashMap()
@ isMutable(mutableMap) 
res16: Boolean = true

ammal的想法很好。可变集合扩展了mutable.Iterable,所以检查你的集合是否是它的一个实例是不言自明的。

作为一种替代方法:可变集合继承了允许它们在内部发生突变的两个特定特征:GrowableShrinkableGrowable表示可以使用+=操作符对集合进行扩充,而Shrinkable表示可以使用-=操作符对集合进行缩减。

另外,在不可变集合上使用这些操作符也有一个技巧:你的引用必须使用var声明以支持重赋值。但是,对于可变集合,您不需要重赋值,因为这些操作是由前面提到的两个特性支持的,这就是为什么可变集合可以使用val声明的原因。

检查你的集合是否是这两个特征之一的实例意味着它是可变的:

val myMap: mutable.Map[String, Int] = mutable.Map(
"Apples" -> 4,
"Pineapples" -> 1,
"Oranges" -> 10,
"Grapes" -> 7
)
val mySet: mutable.Set[Int] = mutable.Set(1, 2, 3)
val myMap2: Map[String, Int] = Map(
"Apples" -> 4,
"Pineapples" -> 1,
"Oranges" -> 10,
"Grapes" -> 7
)
val mySet2: Set[Int] = Set(1, 2, 3)
println(myMap.isInstanceOf[mutable.Growable[_]])       // true
println(myMap2.isInstanceOf[mutable.Shrinkable[_]])    // false
println(mySet.isInstanceOf[mutable.Shrinkable[_]])     // true
println(mySet2.isInstanceOf[mutable.Shrinkable[_]])    // false

最新更新