My favorites | Sign in
Project Home Downloads Wiki Issues Source
Search
for
KnownLimitations  
Limitations of lambdaj caused by the Java language specification.
Updated Aug 10, 2009 by mario.fu...@gmail.com

lambdaj has a known limitation in both of its main features due to 2 different issues of the java language: lack of reified generics and impossibility to proxy a final class.

In more details the first problem doesn't allow lambdaj to infer the actual type that should be returned by the forEach() method when a null or empty collection is passed to it. That means that the following piece of code:

List<Person> persons = new ArrayList<Person>();
forEach(persons).setLastName("Fusco");

will cause lambdaj to throw an exception because it is not able to decide which actual Class should be proxied. To overcome this problem, when you aren't sure that a given collection has at least one item in it, it is advised to use the forEach() overloaded method that accepts a Class as second parameter as it follows:

forEach(persons, Person.class).setLastName("Fusco");

The second issue caused that when the on() method meets a final class it cannot proxy the returned value. It means that for example the following statement will not work:

List<Person> sortedByNamePersons = sort(persons, on(Person.class).getName().toLowerCase());

Even in this case lambdaj will throw an exception complaining that the requested argument cannot be resolved. To fix this last problem it is necessary to find some workaround in order to "help" lambdaj to work as you expect, probably by adding the method getLowerCaseName() to the Person class.

Comment by sadirud...@gmail.com, Aug 25, 2010

I understand that if Person class is final then exception will be thrown at run time. But I don't understand how you will resolve this issue by adding the method getLowerCaseName() to the Person class.

Please clarify.

Comment by project member mario.fu...@gmail.com, Aug 25, 2010

If the Person class had a method getLowerCaseName() implemented as it follows:

public String getLowerCaseName() {
    return getName().toLowerCase();
}

you could sort the persons on their lower case names as it follows:

List<Person> sortedByNamePersons = sort(persons, on(Person.class).getLowerCaseName());
Comment by sadirud...@gmail.com, Aug 29, 2010

Thanks for your reply.

I still don't understand if Person class is final, how it will proxy the the return value, in this case it is getLowerCaseName().

Comment by project member mario.fu...@gmail.com, Aug 30, 2010

Sorry, I didn't explain myself very well. I didn't mean to say that Person is a final class. In that case of course there isn't any chance that lambdaj could work. My example is a bit more subtle: Person is not a final class, but you meet a final during the methods concatenation. Indeed when you call:

on(Person.class).getName()

it returns a String and this is the final class that cannot be proxy again. So by calling toLowerCase() on it doesn't work. That's why I was suggesting to workaround this problem with the getLowerCaseName() method.

I hope it is clearer now.

Comment by Michal.Margiel@gmail.com, Apr 14, 2011

I am just wondering, why you just don't check "iterable.getIterator().hasNext()" in the first line of the forEach() method to solve "empty list limitation"?

Comment by project member mario.fu...@gmail.com, Apr 22, 2011

I check if the list passed to the forEach is empty and in that case I throw an Exception because I don't know what else I could do, or more specifically I don't know what type of proxy I should return. More in detail consider again the statement of my example:

forEach(persons).setLastName("Fusco");

forEach(persons) returns a proxy of the Person class because I see that there are instances of that class inside the list. If the list is empty I don't know which class should extend the proxy that I return. I have no way to "guess" that I should return a proxy extending the Person class, but if I return a proxy of any other class you will get a ClassCastException?? on the subsequent invocation of the setLastName() method.

I hope this clarifies better this issue.

Comment by Michal.Margiel@gmail.com, Apr 28, 2011

OK, now it is clear.. I thought that in case of empty collection you could just return nothing, but then you would get NPE at ".setLastName("Fusco");

Thanks!

btw, You have done a great job with lambdaj - I simple love it!


Sign in to add a comment
Powered by Google Project Hosting