For work I have made a presentation about Java 8 project lambda and of course also some simple code illustrating some of the points. The overall reasons for Java 8 are:
- More concise code (for classes that have just one method & collections). “We want the reader of the code to have to wade through as little syntax as possible before arriving at the “meat” of the lambda expression.” – Brian Goetz (http://cr.openjdk.java.net/~briangoetz/lambda/lambda-state-4.html)
- Ability to pass around functionality, not just data
- Better support for multi core processing
All examples are runnable on the following version of Java 8 downloaded from here:
openjdk version "1.8.0-ea" OpenJDK Runtime Environment (build 1.8.0-ea-lambda-nightly-h3876-20130403-b84-b00) OpenJDK 64-Bit Server VM (build 25.0-b21, mixed mode)
The simplest case:
public class ThreadA {
public static void main(String[] args) {
new Thread(new Runnable() {
@Override
public void run() {
System.err.println("Hello from anonymous class");
}
}).start();
}
}public class ThreadB {
public static void main(String[] args) {
new Thread(() -> {
System.err.println("Hello from lambda");
}).start();
}
}Note the syntax, informally as
()|x|(x,..,z) -> expr|stmt
The arrow is a new operator. And note the conciseness of the second piece of code compared to the more bulky first piece.
Collections:
First let me introduce an simple domain and some helpers
public class Something {
private double amount;
public Something(double amount) {
this.amount = amount;
}
public double getAmount() {
return amount;
}
public String toString() {
return "Amount: " + amount;
}
}
public class Helper {
public static List<Something> someThings() {
List<Something> things = new ArrayList<>();
things.add(new Something(99.9));
things.add(new Something(199.9));
things.add(new Something(299.9));
things.add(new Something(399.9));
things.add(new Something(1199.9));
return things;
}
}
public interface Doer<T> {
void doSomething(T t);
}Lets do some filtering and sorting Java 7 style:
public class CollectionA {
public static void main(String... args) {
List<Something> things = Helper.someThings();
System.err.println("Filter");
List<Something> filtered = filter(things);
System.err.println(filtered);
System.err.println("Sum");
double sum = sum(filtered);
System.err.println(sum);
}
public static List<Something> filter(List<Something> things) {
List<Something> filtered = new ArrayList<>();
for (Something s : things) {
if (s.getAmount() > 100.00) {
if (s.getAmount() < 1000.00) {
filtered.add(s);
}
}
}
return filtered;
}
public static double sum(List<Something> things) {
double d = 0.0;
for (Something s : things) {
d += s.getAmount();
}
return d;
}
}And now Java 8 style – streaming:
import java.util.stream.Collectors;
public class CollectionB {
public static void main(String... args) {
List<Something> things = Helper.someThings();
System.err.println("Filter lambda");
List<Something> filtered = things.stream().parallel().filter( t -> t.getAmount() > 100.00 && t.getAmount() < 1000.00).collect(Collectors.toList());
System.err.println(filtered);
System.err.println("Sum lambda");
double sum = filtered.stream().mapToDouble(t -> t.getAmount()).sum();
System.err.println(sum);
}
}The import java.util.function.* interfaces & method references
public class CollectionC {
public static void main(String... args) {
List<Something> things = Helper.someThings();
System.err.println("Do something");
doSomething(things, new Doer<Something>() {
@Override
public void doSomething(Something t) {
System.err.println(t);
}
});
}
public static void doSomething(List<Something> things, Doer<Something> doer) {
for (Something s : things) {
doer.doSomething(s);
}
}
}Replace our Doer interface with the standard Consumer interface (previously known as Block)
import java.util.function.Consumer;
public class CollectionD {
public static void main(String... args) {
List<Something> things = Helper.someThings();
System.err.println("Do something functional interfaces");
consumeSomething(things, new Consumer<Something>() {
@Override
public void accept(Something t) {
System.err.println(t);
}
});
System.err.println("Do something functional interfaces, using lambda");
consumeSomething(things, (t) -> System.err.println(t));
System.err.println("Do something functional interfaces, using lambda method reference (new operator ::) ");
consumeSomething(things, System.err::println);
System.err.println("Do something functional interfaces, using stream");
things.stream().forEach(new Consumer<Something>() {
@Override
public void accept(Something t) {
System.err.println(t);
}
});
System.err.println("Do something functional interfaces, using stream and method reference");
things.stream().forEach(System.err::println);
}
public static void doSomething(List<Something> things, Doer<Something> doer) {
for (Something s : things) {
doer.doSomething(s);
}
}
public static void consumeSomething(List<Something> things, Consumer<Something> consumer) {
for (Something s : things) {
consumer.accept(s);
}
}
}Map, reduce, lazy & optional
import java.util.List;
import java.util.NoSuchElementException;
import java.util.Optional;
import java.util.stream.Collectors;
public class Various {
public static void main(String... args) {
List<Something> things = Helper.someThings();
//Map
System.err.println(things.stream().map((Something t) -> t.getAmount()).collect(Collectors.toList()));
//Reduce
double d = things.stream().reduce(new Something(0.0), (Something t, Something u) -> new Something(t.getAmount() + u.getAmount())).getAmount();
System.err.println(d);
//Reduce again
System.err.println(things.stream().reduce((Something t, Something u) -> new Something(t.getAmount() + u.getAmount())).get());
//Map/reduce
System.err.println(things.stream().map((Something t) -> t.getAmount()).reduce(0.0, (x, y) -> x + y));
//Lazy
Optional<Something> findFirst = things.stream().filter(t -> t.getAmount() > 1000).findFirst();
System.err.println(findFirst.get());
//Lazy no value
Optional<Something> findFirstNotThere = things.stream().filter(t -> t.getAmount() > 2000).findFirst();
try {
System.err.println(findFirstNotThere.get());
} catch (NoSuchElementException e) {
System.err.println("Optional was not null, but its value was");
}
//Optional one step deeper
things.stream().filter(t -> t.getAmount() > 1000).findFirst().ifPresent(t -> System.err.println("Here I am"));
}
}Reference: Java 8 lambda walkthrough from our JCG partner Kim Saabye Pedersen at the Kim Saabye Pedersen’s blog blog.
Do you want to know how to develop your skillset to become a Java Rockstar?
Subscribe to our newsletter to start Rocking right now!
To get you started we give you our best selling eBooks for FREE!
1. JPA Mini Book
2. JVM Troubleshooting Guide
3. JUnit Tutorial for Unit Testing
4. Java Annotations Tutorial
5. Java Interview Questions
6. Spring Interview Questions
7. Android UI Design
and many more ....
I agree to the Terms and Privacy Policy
Thank you!
We will contact you soon.
👁 Photo of Kim Saabye Pedersen
Kim Saabye PedersenJune 18th, 2013Last Updated: June 17th, 2013
Kim Saabye PedersenJune 18th, 2013Last Updated: June 17th, 2013
0 171 3 minutes read

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