Previous | Home | Next |
Java 8 was released on 18 March 2014. The code name culture is dropped with Java 8 and so no official code name going forward from Java 8.
- Lambda Expressions
- Pipelines and Streams
- Date and Time API
- Default Methods
- Type Annotations
- Nashhorn JavaScript Engine
- Concurrent Accumulators
- Parallel operations
- PermGen Error Removed
- TLS SNI
Lambdas: Lambdas bring anonymous function types in Java (JSR 335): (parameters) -> {body}
Example
Lambdas: Lambdas bring anonymous function types in Java (parameters) -> {body}
Example
Lambdas: Lambdas can be used in place of functional interfaces (interfaces with just one method such as Runnable)
Example
new Thread(new Runnable() { @Override public void run() { System.out.println("It runs !"); } } start(); new Thread(() -> { System.out.println("It runs !"); } ).start();
Lambdas:
Examples of such functional interfaces:
java.lang.Runnable -> run() java.util.concurrent.Callable -> call() java.security.PrivilegedAction -> run() java.util.Comparator -> compare(T o1, T o2) java.awt.event.ActionListener -> actionPerformed (ActionEvent e) java.lang.Iterable -> forEach(Consumer<? super T> action)
Lambdas java.lang.Iterable -> forEach(Consumer<? super T> action) ?!? Isn't this breaking backward compatibility ?!?
Lambdas java.lang.Iterable -> forEach(Consumer<? super T> action) ?!? Isn't this breaking compatibility ?!? No - because forEach is an extension method.
Lambdas Extension methods provide a mechanism for extending an existing interface without breaking backward compatibility.
public interface Iterable<T> { default void forEach(Consumer<? super T> action) { Objects.requireNonNull(action); for (T t : this) { action.accept(t); } } }
Lambdas: This essentially means that lambdas can be used to replace all functional interfaces used in a gazillion of libraries
Moreover lambdas increase performance when used instead of anonymous inner classes because they are implemented with the invokedynamic instruction
In this regard many of the standard JDK class are being refactored to use lambdas
Lambdas Additional functional interfaces are provided by the java.util.function package for use by lambdas such as: o Predicate<T> - one method with param of type T and boolean return type o Consumer<T> - one method with param T and no return type o Function<T, R> - one method with param T and return type R o Supplier<T> - one method with no params and return type T
Stream API: Databases and other programming languages allow us to specify aggregate operations explicitly
The streams API provides this mechanism in the Java platform
The notion of streams is derived from functional programming languages
Stream API : The stream API makes use of lambdas and extension methods
Streams can be applied on collections, arrays, IO streams and generator functions
Stream API: Streams can be finite or infinite
Streams can apply intermediate functions on the data that produce another stream (e.g. map, reduce)
Stream API:
java.util.stream.Stream<T> collection.stream(); java.util.stream.Stream<T> collection.parallelStream(); Useful methods: o filter(Predicate), map(Function), reduce(BinaryOperator), collect() o sum() , min(), max(), count() o anyMatch(), allMatch(), forEach(),
Stream internals int sum = widgets.stream() .filter(w -> w.getColor() == RED) .mapToInt(w -> w.getWeight()) .sum(); • Stream operations are composed into a pipeline • Streams are lazy: computation is performed when the terminal operation is invoked
Method references : Intended to be used in lambda expressions, preventing unnecessary boilerplate
Example: books.stream().map(b -> b.getTitle()) books.stream().map(Book::getTitle) • Lambda parameter list and return type must match the signature of the method
Method references: static methods public class Printers
{ public static void print(String s) {...} } Arrays.asList("a", "b", "c").forEach(Printers::print)
Method references :instance methods (1) public class Document
{ public String getPageContent(int pageNumber) { return this.pages.get(pageNumber).getContent(); } } public static void printPages(Document doc, int[] pageNumbers) { Arrays.stream(pageNumbers) .map(doc::getPageContent) .forEach(Printers::print); }
Method references : instance methods (2)
public class Document { public String getPageContent(int pageNumber) { return this.pages.get(pageNumber).getContent(); } } public static void printDocuments(List<Page> pages) { pages.stream() .map(Page::getContent) .forEach(Printers::print); }
Method references: constructors public static Stream<Page> createPagesFrom(Stream<String> contents) { return contents.map(Page::new). }
Previous | Home | Next |