Tuesday, October 12, 2010

I mentioned last month that I had found a way to add lambdas to the current JDK. I struck me that perhaps many of you had not used lambdas before, so I thought I make a small tutorial on one of the common uses:

Sql like queries against your objects.

Let’s start with the most basic,

Order By

If you where writing an Sql query to get people based on age, you would say

Select *

From People

Order By age

or perhaps

Select *

From People a

Order By a.age

If you had an array of people in C# this would be written as

Linq.OrderBy(people, a => a.GetAge())

Now, to do this in Java is a little more compacted, but very similar

Query.orderBy(people, newS1<Person>(a){{ret(a.getAge());}});

let’s look at some more examples.

Select

Let’s say you wanted to get the names of all the people, you’d write a query like

Select a.names

From people a

Now, let’s translate that into java

Query.select(people, newF1<Person, String>(a){{ret(a.getName());}});

of course, with java you can select more than just primitives, if you wanted the Addresses, you could do that too.

btw: it might be worth expanding the code a bit. I’m cheating a little to help with understanding. For lambdas to work in Java, there is an unfortunate side effect. It gets call 1 extra time. Specifically the first time. So you need to pass in an object. That object in the examples above is pre-defined as ‘a’ but in practice I usually use a blank object

newF1<Person,Boolean>(new Person()){{ret(a.getGradePoint() > 3.8);}}

unfortunately, you can’t use ‘null’ because it would throw a null pointer exception. I also use the null object pattern a lot: Person.Null

of course for averages, the return type F1<InputType, ReturnType> must be a Number.

Min

by now you probably see how easy it would be to get a minimum or maximum, so let’s up the lambda by using a local variable. Let’s find the person who got the closest grade to sally.

finalPerson sally = getPersonByName("Sally");

Query.min(people, newS1<Person>(a, sally){{

ret(Math.abs(a.getGradePoint() - sally.getGradePoint()));}});

You might have noticed the finalkey word, java requires that for locals to be used inside of the lambdas. you might also have noticed that this time I had to pass in 2 parameters (a, sally) to use sally inside you need to add her as a parameter as well. Lastly, I used the class S1<Input> here instead of F1<Input, ReturnType> this is just a convenience class which extends F1, since any where, min, or max queries require the output to be a Comparable object, like Integer, String etc.

Well, I hope this got you interested in what lambdas can do for you. Check out the video and download the jar to get started at http://bit.ly/lambdas