Scala Map.mapValues stackoverflower
发布时间:2020-12-16 09:27:58 所属栏目:安全 来源:网络整理
导读:以下代码导致最后一行出现StackOverflowError. object StackTest extends App{ @tailrec def incrementValues(acc: Map[String,Int],inc: Int): Map[String,Int] = { if(inc == 0) acc else incrementValues(acc.mapValues(_ + 1),inc - 1) } val myMap = in
以下代码导致最后一行出现StackOverflowError.
object StackTest extends App{ @tailrec def incrementValues(acc: Map[String,Int],inc: Int): Map[String,Int] = { if(inc == 0) acc else incrementValues(acc.mapValues(_ + 1),inc - 1) } val myMap = incrementValues(Map("key" -> 0),10000) myMap.foreach(println) } 在Scala 2.11.2中: Exception in thread "main" java.lang.StackOverflowError at scala.collection.MapLike$MappedValues.foreach(MapLike.scala:245) at scala.collection.TraversableLike$WithFilter.foreach(TraversableLike.scala:777) at scala.collection.MapLike$MappedValues.foreach(MapLike.scala:245) at scala.collection.TraversableLike$WithFilter.foreach(TraversableLike.scala:777) at scala.collection.MapLike$MappedValues.foreach(MapLike.scala:245) ... 看看MapLike的源代码,我可以看到它使用的是MappedValues对象,它看起来像一个视图: protected class MappedValues[C](f: B => C) extends AbstractMap[A,C] with DefaultMap[A,C] { override def foreach[D](g: ((A,C)) => D): Unit = for ((k,v) <- self) g((k,f(v))) def iterator = for ((k,v) <- self.iterator) yield (k,f(v)) override def size = self.size override def contains(key: A) = self.contains(key) def get(key: A) = self.get(key).map(f) } /** Transforms this map by applying a function to every retrieved value. * @param f the function used to transform values of this map. * @return a map view which maps every key of this map * to `f(this(key))`. The resulting map wraps the original map without copying any elements. */ def mapValues[C](f: B => C): Map[A,C] = new MappedValues(f) 让它实际映射值的最佳方法是什么? 解决方法
mapValues被认为是一个陷阱,因为它确实只创建了一个包装视图函数,而不是急切地产生一个新的集合.因此,在您的示例中,您将创建嵌套级别为10,000的数据结构.
您可以使用常规地图方法: acc.map(tup => (tup._1,tup._2 + 1)) 要么 acc.map { case (key,value) => (key,value + 1) } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |