2016-09-12 1 views
2

Я использую TreeMap, и он ведет себя странно в следующем коде.Ключи и итерации TreeMap в Scala

Вот код:

import scala.collection.immutable.TreeMap 
object TreeMapTest extends App{ 

    val mp = TreeMap((0,1) -> "a", (0,2) -> "b", (1,3) -> "c", (3,4) -> "f") 
    mp.keys.foreach(println) //A 
    println("****") 
    mp.map(x => x._1).foreach(println) //B 
} 

Как вы можете видеть две линии печати (А и В) должны быть напечатаны то же самое, но результат выглядит следующим образом:

(0,1) 
(0,2) 
(1,3) 
(3,4) 
**** 
(0,2) 
(1,3) 
(3,4) 

Почему это происходит здесь? Интересно, что даже IDE считает, что можно использовать эти два взаимозаменяемо и предлагает замену.

+0

Я не думаю, что порядок «ключей» является проблемой. Похоже, что первый ключ отсутствует во втором примере. – irundaia

+0

А, дух. Благодарю. Я предположил, что это была просто ошибка в вопросе! –

ответ

3

Библиотека коллекции Scala обычно пытается вернуть ту же коллекцию, с которой она начинается, так, например, val seq: Seq[Int] = ...; seq.map(...) вернет Seq, val seq: List[Int] = ...; seq.map(...) вернет List и т. Д. Это не всегда возможно: например. a String считается коллекцией Char, но "ab".map(x => x.toInt), очевидно, не может вернуть String. Аналогично для Map: если вы map каждой пары непары, вы не можете получить Map; но вы сопоставляете каждую пару с парой (Int, Int), и поэтому Scala возвращает Map[Int, Int]. Таким образом, вы не можете получить и (0, 1), и (0, 2): они будут дублировать ключи.

Чтобы избежать этой проблемы, конвертируйте вашу карту в Seq[((Int, Int), String)] сперва: mp.toSeq.map(x => x._1) (или mp.keySet.toSeq).

+0

Интересно, не должен ли компилятор предупредить об этой ситуации? это просто то, что люди могут ошибиться. – Omid

+0

Как бы вы отделили его от ситуаций, когда это предназначено (например, «map.map {case (k, v) => (k, v + 1)}')? Очевидно, что «Map # map» нельзя просто удалить; вы можете попытаться утверждать об этом, но я не ожидал бы успеха. –

Смежные вопросы