Core Java

Playing with Java 8 Lambdas in the JDT

Old Curmudgeon Dude Who Knows Smalltalk
Old Curmudgeon Dude Who Knows Smalltalk

I’ve been playing with the language a bit while tinkering with the Java 8 support under development by the Eclipse Java development tools (JDT) project.

I’ll admit that I’m a little underwhelmed by lambdas in Java 8. This, of course, comes from an Old Dude Who Knows Smalltalk (and LISP/Scheme).

Like any good Smalltalk curmudgeon, when I set about learning how to use lambdas, I naturally decided to implement the known and loved collections.

Starting from something like this:

OrderedCollection employees = new OrderedCollection();
employees.add(new Employee("Wayne", 10));
employees.add(new Employee("Joel", 9));
employees.add(new Employee("Jon", 6));
employees.add(new Employee("Anthony", 8));
employees.add(new Employee("Mary", 2));
employees.add(new Employee("Sue", 3));
employees.add(new Employee("Joanne", 7));
employees.add(new Employee("Shridar", 1));

In classic Java, you’d do something like this to find employees with more than five years of experience:

List longTerm = new ArrayList();
for(Employee employee : employees) 
	if (employee.years > 5) longTerm.add(employee);

Using lambdas, you might do something like this:

OrderedCollection longTerm = 
	employees.select(employee -> employee.years > 5);

It’s a little tighter than classic Java, and I personally find it very readable and understandable; readers with different experiences may have a different option. I believe that it is way better than the equivalent implementation with an anonymous class:

OrderedCollection longTerm = employees.select(new SelectBlock() {
	@Override
	public boolean value(Employee employee) {
		return employee.years > 5;
	}
});

Anonymous classes make babies cry.

Of course, babies aren’t particularly happy about the implementation of select() either:

public class OrderedCollection<T> extends ArrayList<T> {
	...
	public OrderedCollection<T> select(SelectBlock<T> block) {
		OrderedCollection<T> select = new OrderedCollection<T>();
		for(T value : this) {
			if (block.value(value)) select.add(value);
		}
		return select;
	}
	...
}

Lambdas are syntactic sugar for anonymous classes, and do arguably make some code easier to read. For my rather simplistic example, the benefit over the direct use of a for-loop is marginal from a readability point-of-view, but it’s far easier to understand than the anonymous class example. From a performance point-of-view, I expect that using lambdas or anonymous classes in this context would be something like an order of magnitude worse than just using a for-loop.

One of the cooler things that we do in Smalltalk is create our own control structures. Instead of creating a whole new collection, you could create custom iterators, e.g.:

payroll.longTermEmployeesDo(employee -> payroll.giveEmployeeARaise(employee));

Or something like that. I’m not sure if this makes it better or not.

Simple collections might not be the best use of lambdas. Lambdas are not quite as useful (or, I believe, as efficient) as blocks in Smalltalk. I’ll need to spend a little more time tinkering with examples where the use of anonymous classes is more natural in Java (Runnables and listeners seem like an obvious place to start).

Unfortunately, I think that trying to implement Smalltalk-like collections using lambdas in Java 8 will also make babies cry.

As a parting shot… try to wrap your brain around this:

double average = (double)employees.inject(0, 
	(sum, employee) -> sum + employee.years) / employees.size();

Totally readable. Totally.

Modified on Feb 18/2014. My initial observations led me to believe that lambdas are syntactic sugar for anonymous classes. I’ve since learned that this is not the case. Further, there are some optimizations that I need to better understand. I’ve struck out the incorrect statements (but have otherwise left it for posterity).

 

Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

2 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Ram
Ram
10 years ago

Hi,

I suppose lambdas are not syntax sugar for inner classes like Scala, in Java 8 they are compiled to a static method inside the same class and invoked using invokedynamic. Please refer http://cr.openjdk.java.net/~briangoetz/lambda/lambda-translation.html and http://java.dzone.com/articles/compiling-lambda-expressions the first source dates back to 2012 and is a draft which may have changed, but when i decompiled a class with lambda was able to see it compiled as a private static method instead of an inner class. Correct me if I am wrong.

Ram

Wayne
Wayne
10 years ago

Nope. You’re right. I was wrong. I’ve updated the article to reflect this. Unfortunately, the strike-through that I used to indicate my errors isn’t reflected in this copy of my original

http://waynebeaton.wordpress.com/2014/02/14/playing-with-java-8-lambdas-in-the-jdt/

Back to top button