TreeSet在映射后不遵守顺序

时间:2014-09-26 19:32:36

标签: scala map treeset

我不知道如何解释/理解有关TreeSet和map函数的以下行为。

我想我在拼图中错过了一块。对此事的任何启示都将受到欢迎。

scala> class Person(val name: String, val age: Int) extends Ordered[Person]{
     |   def compare(that: Person) = {
     |     val nameComparison = name.compareToIgnoreCase(that.name)
     |     if(nameComparison != 0){
     |       nameComparison
     |     }else{
     |       age.compareTo(that.age)
     |     }
     |   }
     |   override def toString = s"$name || $age"
     | }
defined class Person

scala> import scala.collection.immutable.TreeSet
import scala.collection.immutable.TreeSet

scala> val tsPersons = TreeSet(
     |   new Person("Vivi", 31),
     |   new Person("ViVi", 4),
     |   new Person("vivi", 14)
     | )//1) printed in expected order
tsPersons: scala.collection.immutable.TreeSet[Person] = TreeSet(ViVi || 4, vivi || 14, Vivi || 31)

scala> tsPersons.map(p => p) //2) printed in expected order
res0: scala.collection.immutable.SortedSet[Person] = TreeSet(ViVi || 4, vivi || 14, Vivi || 31)

scala> tsPersons.map(p => (p.name, p.age)) //3) order messed up
res1: scala.collection.immutable.SortedSet[(String, Int)] = TreeSet((ViVi,4), (Vivi,31), (vivi,14))

scala> tsPersons.toList.map(p => (p.name, p.age)) //4) printed in expected order
res2: List[(String, Int)] = List((ViVi,4), (vivi,14), (Vivi,31))

在打印“1)”中,我可以看到tsPersons正确排序。

在打印“2)”和“3)”中,地图方法的元素顺序不一致。

最后,在使用toList方法打印“4)”时,我可以处理正确排序的List,因此列表上的map方法可以正常使用之前无效的函数文字p => (p.name, p.age)

我确定还有一些我不了解的有关Sorted或TreeSet或map的内容。

提前感谢您的帮助!

1 个答案:

答案 0 :(得分:5)

如果您了解map TreeSet的工作原理,您就会明白实际发生了什么。在map内创建新TreeSet并填充原始树集的转换元素。由于新树集将根据自己的自然顺序排序新元素,因此您会得到混乱的结果。

因此,在第二种情况下,您使用Person元素填充新树集,并且它们被命令遵守Person的compare方法。

但是在#3的情况下,你会得到新的TreeSet,其中包含按元组排序排序的元组,这是由第一个元组的元素排序,其中的元素被第二个元素破坏。

在第四种情况下,您首先将您的设置转换为列表,再次在toList内创建新的列表生成器,并使用原始设置保留顺序中的元素填充(如列表是有序集合)。因此,当您在列表元素上调用map时,将保留初始顺序(对于您的树集和列表也是如此)。

希望这能帮助您了解正在发生的事情。如果您仍需要澄清,请不要犹豫。