Scala: использование HashMap со значением по умолчанию
У меня есть изменяемый HashMap и хотел бы использовать его, как словарь по умолчанию. Очевидным методом является использование getOrElse и предоставление значения по умолчанию каждый раз как второе значение. Однако это кажется немного неэлегантным в моем случае использования, поскольку значение по умолчанию не изменяется.
var x = HashMap(1 -> "b", 2 -> "a", 3 -> "c")
println(x.getOrElse(4, "_")
println(x.getOrElse(5, "_"))
// And so on...
println(x.getOrElse(10, "_"))
Есть ли способ создать HashMap (или аналогичный класс), чтобы попытка доступа к undefined ключам возвращала значение по умолчанию, установленное при создании HashMap? Я заметил, что HashMap.default просто настроен на исключение исключения, но мне интересно, можно ли это изменить...
Ответы
Ответ 1
Попробуйте следующее:
import collection.mutable.HashMap
val x = new HashMap[Int,String]() { override def default(key:Int) = "-" }
x += (1 -> "b", 2 -> "a", 3 -> "c")
Тогда:
scala> x(1)
res7: String = b
scala> x(2)
res8: String = a
scala> x(3)
res9: String = c
scala> x(4)
res10: String = -
Ответ 2
Ничего себе, мне довелось посетить эту тему ровно через год после того, как я отправил свой последний ответ здесь.: -)
Scala 2.9.1. mutable.Map
имеет метод withDefaultValue
. Сеанс REPL:
scala> import collection.mutable
import collection.mutable
scala> mutable.Map[Int, String]().withDefaultValue("")
res18: scala.collection.mutable.Map[Int,String] = Map()
scala> res18(3)
res19: String = ""
Ответ 3
scala> val x = HashMap(1 -> "b", 2 -> "a", 3 -> "c").withDefaultValue("-")
x: scala.collection.immutable.Map[Int,java.lang.String] = Map((1,b), (2,a), (3,c))
scala> x(3)
res0: java.lang.String = c
scala> x(5)
res1: java.lang.String = -
EDIT:
Для mutable.HashMap
вы можете сделать следующее:
scala> import collection.mutable
import collection.mutable
scala> val x = new mutable.HashMap[Int, String] {
| override def apply(key: Int) = super.get(key) getOrElse "-"
| }
x: scala.collection.mutable.HashMap[Int,String] = Map()
scala> x += (1 -> "a", 2 -> "b", 3 -> "c")
res9: x.type = Map((2,b), (1,a), (3,c))
scala> x(2)
res10: String = b
scala> x(4)
res11: String = -
Там может быть лучший способ сделать это. Подождите, пока другие ответят.
Ответ 4
Я больше парень из java... но если getOrElse
не является окончательным, почему бы вам просто не расширить HasMap
и предоставить что-то вроде этого:
override def getOrElse(k: Int, default: String) = {
return super.getOrElse(k,"_")
}
Примечание: синтаксис, вероятно, запутан, но, надеюсь, вы получите точку