Самый эффективный способ сделать это - прочитать все в изменяемые структуры и затем в конце преобразовать в неизменяемые, но это может потребовать много избыточного кодирования для классов с большим количеством полей. Поэтому вместо этого рассмотрите возможность использования того же шаблона, который использует базовая коллекция: задание с новой задачей - это новое задание .
Вот пример, который не беспокоит даже чтение списка вакансий - он выводит его из списка задач. (Это пример, который работает в 2.7.x; последние версии 2.8 используют «Source.fromPath» вместо «Source.fromFile».)
object Example {
class Task(val id: String) {
override def toString = id
}
class Job(val id: String, val tasks: Set[Task]) {
def this(id0: String, old: Option[Job], taskID: String) = {
this(id0 , old.getOrElse(EmptyJob).tasks + new Task(taskID))
}
override def toString = id+" does "+tasks.toString
}
object EmptyJob extends Job("",Set.empty[Task]) { }
def read(fname: String):Map[String,Job] = {
val map = new scala.collection.mutable.HashMap[String,Job]()
scala.io.Source.fromFile(fname).getLines.foreach(line => {
line.split("\t") match {
case Array(j,t) => {
val jobID = j.trim
val taskID = t.trim
map += (jobID -> new Job(jobID,map.get(jobID),taskID))
}
case _ => /* Handle error? */
}
})
new scala.collection.immutable.HashMap() ++ map
}
}
scala> Example.read("tasks.txt")
res0: Map[String,Example.Job] = Map(JA -> JA does Set(T1, T3, T2), JB -> JB does Set(T2, T1), JC -> JC does Set(T1))
Альтернативный подход будет читать список заданий (создание заданий как новое задание (jobID, Set.empty [Task])), а затем обрабатывать состояние ошибки, когда список заданий содержит запись, которой нет в задании список. (Вам все равно придется обновлять карту списка заданий каждый раз, когда вы читаете новое задание.)