Reputation: 177
I don't know how to explain/understand the following behavior regarding TreeSet and the map function.
I think I'm missing a piece in the puzzle. Any light upon the matter will be very welcomed.
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))
In printing "1)" I can see tsPersons being sorted correctly.
In printings "2)" and "3)" the order of the elements for the map method is not consistent.
Finally, in printing "4)" with the toList method I can work on the correctly ordered List, so the map method on the list works fine with the same function literal p => (p.name, p.age)
that didn't work before.
I'm sure there is something else I don't know about Sorted or TreeSet or map.
Thanks for your help in advance!
Upvotes: 2
Views: 318
Reputation: 10882
If you understand how map
for TreeSet
works, you'll understand what is actually happening. Inside map
new TreeSet
is created and filled with transformed elements of original tree set. As new tree set will order new elements according to their own natural ordering, you get the messed result.
So, in second case you fill new tree set with Person
elements and they are ordered respecting Person's compare
method.
But in case #3 you get new TreeSet
filled with tuples that are ordered according to tuple's ordering, which is ordering by first tuple's element with ties broken by second element.
In forth case you first convert your set to list, once again, inside toList
new list builder is created and populated with elements from your original set preserving order (as List is ordered collection). So when you call map on list's elements, initial order is preserved (same for your tree set and list).
Hope this will help you to understand what's happening. If you still need some clarification, don't hesitate to ask.
Upvotes: 5