Несоответствия Scala Collections - PullRequest
5 голосов
/ 04 ноября 2010

Почему не хватает согласованности между наборами и списками в Scala Collections API?

Например, есть неизменный Set, но также изменяемый. Если я хочу использовать последнее, я могу просто сделать это:

val set = Set[A]()
set += new A

Однако нет изменяемого списка как такового. Если я хочу написать похожий фрагмент кода с использованием списков, какую структуру данных использовать? LinkedList звучит как хороший кандидат, потому что он изменчив, но не определен метод + =. ListBuffer, кажется, удовлетворяет требованиям, но это не список.

После прочтения 2.8 документации к коллекциям я прихожу к выводу, что MutableList, вероятно, лучше всего подходит.

Мне все еще хотелось бы, чтобы был scala.collection.mutable.List.

Ответы [ 5 ]

20 голосов
/ 04 ноября 2010

Причина этого заключается в том, что Java выбрала функциональный тип List для обозначения чего-то такого, чего нет (т.е. java.util.List не является списком ).

Вероятно, для функционального языка программирования не имеет смысла иметь mutable List, поскольку такой тип является оксюмороном. Следовательно ListBuffer или ArrayBuffer. Или просто используйте IndexedSeq, из которых есть изменчивые и неизменные реализации

9 голосов
/ 05 ноября 2010

Последовательность / список аналога Set в библиотеках коллекций Scala: Seq. List - это просто конкретная неизменная реализация Seq, как и Vector. ArrayBuffer или ListBuffer являются типичными реализациями mutable.Seq.

3 голосов
/ 04 ноября 2010

ArraySeq может быть тем, что вы ищете, кроме + = исключительно медленно.Вы также можете использовать java.util.ArrayList и импортировать коллекцию. JavaConversions ._

Кажется, в Scala отсутствует хорошая изменяемая коллекция типа списка с постоянным индексом времени (например, ArrayList для java).

В любом случае, обратите внимание, что «Список» относится именно к типу «scala.immutable.List».Поэтому Seq (или другой более абстрактный тип коллекции) - это тип, который следует ожидать в методах, а не в «List», если вы хотите обобщить неизменяемые / изменяемые коллекции.

Более идеальным является запрос IndexedSeq, которыйЭто означает, что операция индекса выполняется для этой коллекции.Однако я не уверен, что ListBuffer попадает в эту категорию.

2 голосов
/ 05 ноября 2010

Потому что Set - это просто черта - она ​​абстрактна и требует реализации. Таким образом, можно говорить о классах, которые mutable.Set или immutable.Set.

Между тем, List - это класс, реализация (абстрактного) признака immutable.LinearSeq. Никогда не может быть другого класса, который также является List. Однако вы обнаружите, что является чертой mutable.LinearSeq.

В терминах Java вы сравниваете интерфейсы с классами - они различны.

0 голосов
/ 19 июля 2011

Не забудьте scala.collection.mutable.{LinkedList,DoubleLinkedList}. Они изменчивы, и они LinearSeq. Мутация немного странная - вы можете изменить голову, назначив ссылку elem, а хвост, присвоив ссылку next.

Например, этот цикл изменяет все отрицательные значения на ноль.

val lst = collection.mutable.LinkedList(1, -2, 7, -9)
var cur = lst
while (cur != Nil) { 
  if (cur.elem < 0) cur.elem = 0
  cur = cur.next 
}

Этот цикл удаляет каждый второй элемент из списка.

var cur = lst
while (cur != Nil && cur.next != Nil) { 
  cur.next = cur.next.next
  cur = cur.next 
}

Я не утверждаю, что они лучше, чем неизменный Список. Я просто отмечаю, что в Scala есть изменяемые списки, которые выглядят довольно похоже на то, что вы видели в своем классе структур данных.

...