Відповіді:
Scala List
є непорушною рекурсивної структурою даних , яка є такою фундаментальною структурою в Scala, що ви повинні (можливо) будете використовувати його набагато більше , ніж Array
(що насправді змінюваний - незмінний аналог з Array
це IndexedSeq
).
Якщо ви їдете з фону Java, то очевидно , паралель , коли використовувати LinkedList
більш ArrayList
. Перші , як правило , використовується для списків , які тільки коли - або перетинали (і розмір яких не відомий заздалегідь) , тоді як останній повинен використовуватися для списків , які або мають відомий розмір (або максимальний розмір) або для яких швидкий довільний доступ важливо.
ListBuffer
забезпечує конвертацію в постійному часі, до List
якої можна скористатися лише однією причиною, ListBuffer
якщо потрібна така пізня конверсія.
Скала Array
повинна бути реалізована в JVM Java-масивом, а отже, Array[Int]
може бути набагато ефективнішою (як an int[]
), ніж а List[Int]
(яка вказує її вміст, якщо ви не використовуєте найновіші версії Scala, які мають нову @specialized
функцію) .
Однак я вважаю, що використання Array
s у Scala слід звести до мінімуму, тому що вам здається, що вам справді потрібно знати, що відбувається під кришкою, щоб вирішити, чи справді ваш масив буде підкріплений необхідним примітивним типом, чи може бути в коробці як обгортковий тип.
Окрім вже опублікованих відповідей, ось деякі конкретики.
Хоча а - Array[A]
це буквально масив Java, a List[A]
- це незмінна структура даних, яка є Nil
(порожній список) або складається з пари (A, List[A])
.
Різниці в продуктивності
Array List
Access the ith element θ(1) θ(i)
Delete the ith element θ(n) θ(i)
Insert an element at i θ(n) θ(i)
Reverse θ(n) θ(n)
Concatenate (length m,n) θ(n+m) θ(n)
Count the elements θ(1) θ(n)
Відмінності пам’яті
Array List
Get the first i elements θ(i) θ(i)
Drop the first i elements θ(n-i) θ(1)
Insert an element at i θ(n) θ(i)
Reverse θ(n) θ(n)
Concatenate (length m,n) θ(n+m) θ(n)
Тому, якщо вам не потрібен швидкий випадковий доступ, вам потрібно порахувати елементи, або чомусь вам потрібні деструктивні оновлення, a List
краще, ніж an Array
.
list = list.drop(i)
. Або: Чи виникає якась магія за капотом?
drop
ніколи, не потрібно копіювати частину списку, яка не була скинута. Наприклад, (x::xs).drop(1)
це точно xs
, а не "копія" xs
.
Масив є змінним, тобто ви можете змінювати значення кожного індексу, тоді як Список (за замовчуванням) є незмінним, тобто новий список створюється кожного разу, коли ви вносите зміни. У більшості випадків це більш «функціональний» стиль роботи з незмінними типами даних , і ви , ймовірно , слід спробувати використовувати список з конструкціями , як yield
, foreach
, match
і так далі.
Для характеристик продуктивності масив швидший із випадковим доступом до елементів, тоді як список швидший під час попереднього (додавання) нових елементів. Ітерація над ними порівнянна.
iterate over
через кеш