在这种情况下我需要不可变的地图吗?

时间:2015-04-02 09:32:41

标签: scala

我试图在一个不可变的Map中维护一个Document of List类:

object DocumentModel extends App{

  case class Document(title : String , text : String)


  val documentMap = Map[org.joda.time.DateTime , Document]()


  def addDocument(d : Document) :  Map[org.joda.time.DateTime , Document]= {
    documentMap + (new org.joda.time.DateTime -> d)
  }

  addDocument(Document("title" , "text"))

  println("size is "+addDocument(Document("title" , "text")).size);


}

当访问documentMap时,其大小始终为1,因为每次方法addDocument中返回的Map只是附加元素相同的不可变集合。

如何附加到不可变Map并返回其值,还是需要使用不可变Map?

更新:

选项是使用:

object DocumentModel extends App{

  case class Document(title : String , text : String)

  var id = Map[org.joda.time.DateTime , Document]()

  def addDocument(d : Document) :  Map[org.joda.time.DateTime , Document]= {
    id = id + (new org.joda.time.DateTime -> d)

    id
  }

  addDocument(Document("title" , "text"))

  println("size is "+addDocument(Document("title" , "text")).size);
  println("size is "+addDocument(Document("title" , "text")).size);


}

但这不是线程安全的

2 个答案:

答案 0 :(得分:0)

我的印象是你想通过编写不可变对象(DocumentModel)来创建可变对象(Map),这不会起作用。

正如您所发现的,第一个解决方案是对Map使用可变documentMap。因此,您将获得一个可变的DocumentModel

val documentMap = mutable.Map[org.joda.time.DateTime , Document]()

您将能够以下列方式使用您的可变DocumentModel

val docs = DocumentModel()
docs.addDocument("title1", "text1")
docs.addDocument("title2", "text2")
docs.addDocument("title3", "text3")

第二种解决方案是在DocumentModel方法中返回新的addDocument

def addDocument(d : Document) :  Map[org.joda.time.DateTime , Document]= {
    val newDocumentMap = documentMap + (new org.joda.time.DateTime -> d)
    DocumentModel(newDocumentMap)
}

因此,您将获得一个不可变的DocumentModel,其使用方式不同:

val docs0 = DocumentModel()
val docs1 = docs0.addDocument("title1", "text1")
val docs2 = docs1.addDocument("title2", "text2")
val docs3 = docs2.addDocument("title3", "text3")

val docs = DocumentModel().addDocument("title1", "text1")
                          .addDocument("title2", "text2")
                          .addDocument("title3", "text3")

答案 1 :(得分:0)

在您的代码中,方法addDocument根本不会更改documentMap成员,它只会返回一个包含一个元素的新地图。成员documentMap保持空白。

如果您想保留所有添加文档的地图,您有两种选择:

使用val成员documentMap中的可变地图,或使用带有不可变地图的var成员documentMap

您选择哪种方法取决于您打算如何使用地图。如果你永远不会返回整个地图,那么使用可变地图是可以的。但是,如果您从某些公共方法返回地图,那么我选择了var - 不可变方法。

因为您的方法addDocument会返回地图,所以我会使用var - 不可变的方法,如同mohit建议的那样。