2015-12-08 2 views
1

Есть ли общий способ преобразования некоторой изменчивой коллекции в Scala в ее неизменяемый экземпляр (при условии, что он один)?Преобразование измененной коллекции в неизменяемую коллекцию в Scala

Пример использование случай ...

private[this] val _collection: mutable.TreeSet[A] 

def collection: immutable.TreeSet[A] = { 
    // convert mutable _collection to immutable version for public consumption 
} 

Я попробовал следующее ...

def collection: immutable.TreeSet[A] = { 
    _collection.to[immutable.TreeSet[A]] 
} 

... но это привело к стандартному сообщению об ошибке на компиляции ...

scala.collection.immutable.TreeSet[A] takes no type parameters, expected: one 

... любые мысли?

+0

'to' требует конструктора типа, например. '_collection.to [immutable.TreeSet]'. – Lee

+0

@Lee, я попробовал это и получил следующую ошибку компиляции: 'Невозможно построить коллекцию типа scala.collection.immutable.TreeSet [A] с элементами типа A на основе коллекции типа Nothing' – davidrpugh

ответ

2

Я подозреваю, что immutable.TreeSet должен быть создан с нуля:

trait Aaa[A] { 
    val _collection: mutable.TreeSet[A] 

    def collection: immutable.TreeSet[A] = { 
     immutable.TreeSet.empty[A] ++ _collection 
    } 
    } 

EDIT для прослеживания комментарий

от источника-2.11.7 Scala код immutable.TreeSet:

import scala.collection.immutable.{RedBlackTree => RB} 

private def newSet(t: RB.Tree[A, Unit]) = new TreeSet[A](t) 

Unfortun ately newSet является приватным и от mutable.TreeSet:

class TreeSet[A] private (treeRef: ObjectRef[RB.Tree[A, Null]], from: Option[A], until: Option[A]) 

Конструктор является частным тоже ...

+0

Это работает. Интересно, почему невозможно использовать метод 'to [Col]? Возможно, потому, что я пытаюсь сделать это с помощью упорядоченной коллекции. – davidrpugh

+0

Не уверен. Для 'mutable' и' immutable' 'TreeSet' базовая структура данных является' scala.collection.immutable.RedBlackTree'! –

0

Если вы не заботитесь о конкретной реализации Set вы получите в конце концов, путь только val immutableSet = mutableSet.toSet

Если вы специально хотите неизменны TreeSet, а не только какой-либо Set, вам нужно будет использовать Breakout:

val immutableSet: immutable.TreeSet[T] = mutableSet.map(identity)(collection.breakOut) 
+0

Я хочу, чтобы общественный просмотр в частной сортированной коллекции поддерживал отсортированный порядок. Я беспокоюсь, что использование 'toSet' может не поддерживать базовый порядок. Является ли ваше предложение более эффективным, чем текущий принятый ответ? Кажется, что текущий ответ - O (n log n). «Карта» в вашем решении - O (n). Не знаю, какие характеристики производительности для 'breakOut' ... – davidrpugh

+0

@davidrpugh Я думаю, сложность такая же, это немного короче и более идиоматично. Также рассмотрим следующее: 'def collection: collection.SortedSet [A] = _collection.clone' Это дает вам неизменный вид в постоянное время. – Dima

+0

Не могли бы вы рассказать о том, как использовать «клон»? Это похоже на то, что нужно: неизменное представление об изменяемых данных как можно более эффективно. – davidrpugh