Симптомы могут быть упрощены до:
scala> collection.mutable.ListMap(1 -> "one", 2 -> "two").foreach(println)
(2,two)
(1,one)
scala> collection.immutable.ListMap(1 -> "one", 2 -> "two").foreach(println)
(1,one)
(2,two)
"Сортировка" в вашем коде не является ядром проблемы, ваш вызов ListMap
использует вызов ListMap.apply
от собеседникаобъект, который создает карту списка, поддерживаемую изменяемым или неизменным списком.Правило заключается в том, что порядок вставки будет сохранен.
Разница, по-видимому, заключается в том, что изменяемый список поддерживается списком неизменяемого , и вставка происходит спереди.Вот почему при итерации вы получаете поведение LIFO.Я все еще смотрю на неизменный, но держу пари, что вставки эффективно сзади.Edit, я передумал: insert, вероятно, впереди, но, похоже, метод immutable.ListMap.iterator
решает обратить результат с toList.reverseIterator
на возвращенном итераторе.Я думаю, что стоит внести это в список рассылки.
Может ли документация быть лучше?Конечно.Есть ли боль?Не совсем, я не позволю этому случиться.Если документация неполная, целесообразно проверить поведение или посмотреть на источник, прежде чем выбирать структуру, а не другую.
На самом деле, может возникнуть боль, если команда Scala решит изменить поведение на более позднем этапе.время и чувство, что они могут, потому что поведение эффективно недокументировано, и нет никакого контракта.
Чтобы рассмотреть ваш вариант использования, описанный в комментарии, скажем, вы собрали счетчик частоты строк на карте (изменяемой или неизменной):
val map = Map("A" -> 5, "B" -> 12, "C" -> 2, "D" -> 9, "E" -> 18, "B" -> 5)
Поскольку вы тольконужно отсортировать один раз в конце, вы можете преобразовать кортежи с карты в seq
и затем отсортировать:
map.toSeq.sortBy(_._2)
// Seq[(java.lang.String, Int)] = ArrayBuffer((C,2), (A,5), (B,5), (D,9), (E,18))