Thursday, August 11, 2011

Play with Scala lists

A friendly colleague of mine asked me today what the "best" way would be to compare two separate, homogeneous lists, containing some instances of a simple data structure. The objects are actually Hibernate entities holding values from 2 database queries. The idea is to test on one particular string property from the Java entities, ignoring other, not relevant properties. The order of the objects should be ignored, and implementing a custom "equals()" method was out of the question.

We could have written something using Apache commons-collections, but I doubt if we would have liked the end result. Using (inner) callback classes implementing "Transformer" will always contain a lot of ugly Java boiler plate code.

I wondered how would it look in Scala, given my very limited knowledge of this language?
package tung


object Tester {
def main(args: Array[String]): Unit = {
/* Create two separate lists of Person objects, containing ID and name. */
var personList1 = List(new Person(1, "john"), new Person(2, "john"), new Person(3, "daisy"), new Person(3, "bart"))
var personList2 = List(new Person(100, "bart"), new Person(101, "john"), new Person(103, "daisy"), new Person(104, "daisy"))
System.out.println(personList1)
System.out.println(personList2)

// Now doing the actual test to check if same names are available
val names1 = personList1.map(_.name).distinct.sort((x, y) => x < y)
val names2 = personList2.map(_.name).distinct.sort((x, y) => x < y)
val equalNames = names1 == names2

// Printing some output
System.out.println(names1)
System.out.println(names2)
System.out.println("names from lists are equal = " + equalNames)
}
}
Output:
List(tung.Person@199a0c7c, tung.Person@33f42b49, tung.Person@6345e044, tung.Person@86c347)

List(tung.Person@f7e6a96, tung.Person@3487a5cc, tung.Person@35960f05, tung.Person@eb42cbf)
List(bart, daisy, john)
List(bart, daisy, john)
names from lists are equal = true
As you can see, the actual tests are 3 simple lines. Probably shorter variations exist, but I'm not the Scala guru. Other languages can do something similar, but the same simplicity with pure Java 6? I don't think so.

Ending note: in the end, he simply chose to write a custom SQL query because of the probable hassle in Java. Would he have done the same if he could use Scala?
Links

No comments: