Rozbuduję trochę mój komentarz. Struktura List[T]
danych from scala.collection.immutable
jest zoptymalizowana do działania w taki sposób, aby działała niezmienna lista w czysto funkcjonalnym języku programowania. Ma bardzo krótki czas przygotowania i zakłada się, że będziesz pracować nad głową prawie przez cały swój dostęp.
Niezmienne listy mogą mieć bardzo krótkie czasy prepend, ponieważ modelują one swoje połączone listy jako serię „komórek przeciw”. Komórka definiuje pojedynczą wartość i wskaźnik do następnej komórki (klasyczny styl pojedynczo połączonych list):
Cell [Value| -> Nil]
Kiedy przechodzisz do listy, tak naprawdę tworzysz tylko jedną nową komórkę, a reszta istniejącej listy jest wskazywana:
Cell [NewValue| -> [Cell[Value| -> Nil]]
Ponieważ lista jest niezmienna, możesz to zrobić bez faktycznego kopiowania . Nie ma niebezpieczeństwa zmiany starej listy i spowodowania, że wszystkie wartości na nowej liście staną się nieprawidłowe. Jednak tracisz możliwość posiadania zmiennego wskaźnika na końcu listy jako kompromis.
To bardzo dobrze nadaje się do rekurencyjnej pracy nad listami. Załóżmy, że zdefiniowałeś własną wersję filter
:
def deleteIf[T](list : List[T])(f : T => Boolean): List[T] = list match {
case Nil => Nil
case (x::xs) => f(x) match {
case true => deleteIf(xs)(f)
case false => x :: deleteIf(xs)(f)
}
}
Jest to funkcja rekurencyjna, która działa wyłącznie na początku listy i wykorzystuje dopasowanie wzorca za pomocą :: ekstraktora. To jest coś, co często widuje się w językach takich jak Haskell.
Jeśli naprawdę chcesz mieć szybkie dodatki, Scala oferuje wiele zmiennych i niezmiennych struktur danych do wyboru. Po stronie zmiennej możesz zajrzeć ListBuffer
. Alternatywnie, Vector
od scala.collection.immutable
ma szybki czas dołączania.