Scala:HashMap 可以针对不同的键使用不同的数据类型吗?
我对 Scala 编程完全陌生,并且遇到以下问题:
我需要一个可以包含许多数据类型(Int、String 等)的 HashMap。在 C++ 中我会使用 BOOST 的 MultiMap。我听说 Scala 中有一个 MultiMap 特征可用。基本上我想要的是:
val map = HashMap[String, ListBuffer[_]]
ListBuffer 元素的具体数据类型将在运行时确定。当我在控制台中测试此实现时,以下结果有效:
scala> val a = new HashMap[String, ListBuffer[_]]()
a: scala.collection.mutable.HashMap[String,scala.collection.mutable.ListBuffer[_]] = Map()
scala> val b = new ListBuffer[String]()
b: scala.collection.mutable.ListBuffer[String] = ListBuffer()
scala> val c = new ListBuffer[Int]()
c: scala.collection.mutable.ListBuffer[Int] = ListBuffer()
scala> b += "String"
res0: b.type = ListBuffer(String)
scala> c += 1
res1: c.type = ListBuffer(1)
scala> a += "String Buffer" -> b
res2: a.type = Map((String Buffer,ListBuffer(String)))
scala> a += "This is an Int Buffer" -> c
res3: a.type = Map((String Buffer,ListBuffer(String)), (This is an Int Buffer,ListBuffer(1)))
所以基本上它有效。我的第一个问题是,是否有可能在 Scala 中实现相同的行为而不使用 ListBuffer 作为间接层。
例如,获取包含以下内容的 Map: Map((String, 1),(String, "String value"), ...)
当我现在尝试使用上面的 ListBuffer-Implementation 时,出现以下类型不匹配错误:
found : _$1 where type _$1
required: _$3 where type _$3
我基本上尝试执行以下操作:
我使用迭代器来迭代映射的键:
var valueIds = new ListBuffer[Int]()
val iterator = map.keys
iterator.foreach(key => { valueIds += setValue((map.apply(key)).last) }
setValue 返回 Int,并且是一种必须对 ListBuffers 最后一个元素执行某些操作的方法。
有谁知道如何解决上述类型不匹配的问题?
感谢您的帮助!
问候
I am totally new to programming with Scala and I have the following problem:
I need a HashMap which can contain many data types (Int, String, etc..). In C++ I would use BOOST's MultiMap. I have heard that in Scala there is a MultiMap trait available. Basically what I want to to is the following:
val map = HashMap[String, ListBuffer[_]]
The concrete datatype of the ListBuffer's elements are to be determined during runtime. When I test this implementation in console the following works:
scala> val a = new HashMap[String, ListBuffer[_]]()
a: scala.collection.mutable.HashMap[String,scala.collection.mutable.ListBuffer[_]] = Map()
scala> val b = new ListBuffer[String]()
b: scala.collection.mutable.ListBuffer[String] = ListBuffer()
scala> val c = new ListBuffer[Int]()
c: scala.collection.mutable.ListBuffer[Int] = ListBuffer()
scala> b += "String"
res0: b.type = ListBuffer(String)
scala> c += 1
res1: c.type = ListBuffer(1)
scala> a += "String Buffer" -> b
res2: a.type = Map((String Buffer,ListBuffer(String)))
scala> a += "This is an Int Buffer" -> c
res3: a.type = Map((String Buffer,ListBuffer(String)), (This is an Int Buffer,ListBuffer(1)))
So basically it works. My first question is, whether there is a possiblity to implement the same behaviour in Scala without using the ListBuffer as layer of indirection.
E.g getting a Map with the following content: Map((String, 1),(String, "String value"), ...)
When I am now trying to use the ListBuffer-Implementation above, I get the following type mismatch error:
found : _$1 where type _$1
required: _$3 where type _$3
I am basically trying to do the following:
I use an iterator to iterate over the map's keys:
var valueIds = new ListBuffer[Int]()
val iterator = map.keys
iterator.foreach(key => { valueIds += setValue((map.apply(key)).last) }
setValue returns Int and is a method which has to do something with the ListBuffers last element.
Does anybody know how to fix the above mentioned type mismatch?
Thanks for your help!
Regards
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
您需要为每个键存储多个值吗?如果是这样,无论如何都需要使用
ListBuffer
或其他集合。 (Scala 的 MultiMap 存储集,因此如果您需要保存重复项,它们将不起作用。)如果您不需要每个键存储多个值,那么您只需要
Any type:
您现在可能需要进行模式匹配或使用收集来执行任何对值有用的操作:
Do you need multiple values stored per key? If so, using a
ListBuffer
or other collection is necessary anyway. (Scala'sMultiMap
s store sets, so if you need to hold duplicates they won't work.)If you do not need multiple values stored per key, then you just want the
Any
type:where you'll now presumably need to do pattern matching or use collect to do anything useful to the values:
Scala 有一个 MultiMap 类,
我认为这使得当你查看你的代码时就知道你想要什么。
Scala has a MultiMap class
I think that makes sense when looking at your code as to what you want.
如果您使用占位符
_
作为类型参数,则会将其转换为存在类型,即您的定义ListBuffer[_]
变为ListBuffer[A] forSome { type一个}
。这意味着编译器不知道有关该类型A
的任何信息,并且无法对其做出任何假设。最简单的解决方法是简单地使用
ListBuffer[Any]
并用如下内容包装地图:If you use the placeholder
_
as a type parameter this gets translated into an existential type, i.e. your definitionListBuffer[_]
becomesListBuffer[A] forSome { type A }
. This means that the compiler does not know anything about that typeA
and cannot make any assumptions about it.The easiest fix would be to simply use a
ListBuffer[Any]
and wrap the map with something like this:让我建议另一种方法:
Let me suggest one more way: