关于scala中集合的简单问题

时间:2016-12-25 14:42:51

标签: scala scala-collections

我只是在内存中使用虚假数据库模拟api并使用scala.collection.mutable.HashMap[Int, AnyRef]

  1. 哪个是支持并发插入的最佳集合?还有更好的选择吗?

  2. 假设我需要另一种类似Map[Int, AnyRef]的集合,但这次需要对键进行排序。 TreeMap是最好的选择吗?

  3. 提前致谢

3 个答案:

答案 0 :(得分:1)

  

哪个是支持并发插入的最佳集合?还有更好的选择吗?

使用不可变数据结构

  

TreeMap是最好的选择吗?

实现线程安全的直接方法是使用不可变数据 结构。

Scala提供不可变的数据结构。只需导入scala.collection.immutable._

要使用scala.collection.immutable.TreeMap

进行排序

This post tells about how to use TreeMap and provide custom ordering

答案 1 :(得分:0)

这里有两个选择。

您可以使用scala.collection.immutable.HashMap之类的不可变数据结构,它提供高效的不可变哈希映射。您还需要记住,对此地图的每次更新都需要像这样同步:

object Database {
  private var map = new immutable.HashMap[Int, AnyRef]
  def get(index: Int) = map(index)
  def insert(index: Int, value: AnyRef) = 
    synchronized(map = map.updated(index, value))
}

另一种方法是使用并发可变地图,例如scala.collection.concurrent.TrieMap,它不需要额外的锁定:

object Database {
  private val map = new concurrent.TrieMap[Int, AnyRef]
  def get(index: Int) = map(index)
  def insert(index: Int, value: AnyRef) = map.put(index, value)
}

答案 2 :(得分:0)

我不同意上述建议。无论如何你都要有可变状态,最好在数据容器内隔离它,而不是每次都更换容器本身。

最好为此目的使用java容器。对于hashmap,java ConcurrentHashMap是您的最佳选择。对于已排序的实现,您必须明确同步:

 object DB {
   import java.util._
   val hashed = new concurrent.ConcurrentHashMap[String, AnyRef]
   val sorted = Collections.synchronizedMap(new TreeMap[Int, AnyRef])
}

你可以import scala.collection.JavaConversions._隐式地将这些转换为scala地图,以获得好处,例如mapfilter等,但是...... 你可能不应该。在99%的情况下,使用其中任何一个在并发下都不是一个好主意。除了常规getput(以及put/computeIfNotExists案例的ConcurrentHashmap)原语之外的任何内容都是非常重要的,并且使用起来很危险。

将这些视为原始的键值容器,而不是完整的scala集合。