我不知道如何解释/理解有关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的内容。
提前感谢您的帮助!
答案 0 :(得分:5)
如果您了解map
TreeSet
的工作原理,您就会明白实际发生了什么。在map
内创建新TreeSet
并填充原始树集的转换元素。由于新树集将根据自己的自然顺序排序新元素,因此您会得到混乱的结果。
因此,在第二种情况下,您使用Person
元素填充新树集,并且它们被命令遵守Person的compare
方法。
但是在#3的情况下,你会得到新的TreeSet
,其中包含按元组排序排序的元组,这是由第一个元组的元素排序,其中的元素被第二个元素破坏。
在第四种情况下,您首先将您的设置转换为列表,再次在toList
内创建新的列表生成器,并使用原始设置保留顺序中的元素填充(如列表是有序集合)。因此,当您在列表元素上调用map时,将保留初始顺序(对于您的树集和列表也是如此)。
希望这能帮助您了解正在发生的事情。如果您仍需要澄清,请不要犹豫。