Upload
sanjoy-kumar-roy
View
119
Download
2
Tags:
Embed Size (px)
DESCRIPTION
Java 8 is coming soon. In this presentation I have outlined the major Java 8 features. You get information about interface improvements, functional interfaces, method references, lambdas, java.util.function, java.util.stream
Citation preview
Agenda Interface Improvements
Functional Interfaces
Lambdas
Method references
java.util.function
java.util.stream
Interface Improvements
3
Interfaces can now define static methods.
public interface Comparator<T> {
………
public static <T extends Comparable<? super T>> Comparator<T> naturalOrder() {
return (Comparator<T>) Comparators.NaturalOrderComparator.INSTANCE;
}
…………
}
For Example: naturalOrder method in java.util.Comparator
Interface Improvements (cont.)
4
Interfaces can define default methods
public interface A { default void foo(){ System.out.println("Calling A.foo()"); } }
public class MyClass implements A { }
MyClass clazz = new MyClass(); clazz.foo(); // Calling A.foo()
Interface Improvements (cont.)
5
Multiple inheritance?
Interface A
default void foo()
Class MyClass implements A, B
Interface B
default void foo()
Interface Improvements (cont.)
6
public interface A { default void foo(){ System.out.println("Calling A.foo()"); } }
public interface B { default void foo(){ System.out.println("Calling A.foo()"); } }
public class MyClass implements A, B { }
CODE FAILS
Interface Improvements (cont.)
7
public class MyClass implements A, B { default void foo(){ System.out.println("Calling from my class."); } }
This can be fixed :
public class MyClass implements A, B { default void foo(){ A.super.foo(); } }
OR
Calling the default implementation of method foo() from interface A
Overriding in implementation
class
Interface Improvements (cont.)
8
public default void forEach(Consumer<? super T> action) { Objects.requireNonNull(action);
for (T t : this) { action.accept(t);
} }
forEach method in java.lang.Iterable
Another Example
Interface Improvements (cont.)
9
List<Person> persons = asList(new Person("Joe"), new Person("Jim"), new Person("John"));
persons.forEach(p -> p.setLastName("Doe"))
Why do we need default methods in Interface?
Interface Improvements (cont.)
10
Enhancing the behaviour of existing libraries (Collections) without breaking backwards compatibility.
Functional Interface
11
An interface is a functional interface if it defines exactly one abstract method.
@FunctionalInterface public interface Runnable {
public abstract void run();
}
For Example: java.lang.Runnable is a functional interface. Because it has only one abstract method.
Functional Interface (cont.)
12
Functional interfaces are also called Single Abstract Method (SAM) interfaces. Anonymous Inner Classes can be created using these interfaces.
public class MyAnonymousInnerClass { public static void main(String[] args) { new Thread(new Runnable() { @Override public void run() {
System.out.println(“Hello!"); }}).start(); }}
13
public class MyAnonymousInnerClass { public static void main(String[] args) { new Thread(new Runnable() { @Override public void run() {
System.out.println(“Hello!"); }}).start(); }}
UnclearBit excessiveCumbersome
Lambda Expressions can help us
Functional Interface (cont.)
How can lambda expression help us?
14
But before that we need to see:Why are lambda expressions being added to Java?
15
Most pressing reason is:
Lambda expressions make the distribute processing of collections over multiple threads easier.
16
How do we process lists and sets today ?
What is the issue?
Iterator
ClientCode
Collection
Parallel Processing
17
In Java 8 - ClientCode
Collection
f
f f f f
CODE AS A DATA
18
Benefits of doing this:
Collections can now organise their iteration internally.
Responsibility for parallelisation is transferred from client code to library code.
19
But client code needs a simple way of providing a function to the collection methods.
Currently the standard way of doing this is by means of an anonymous class implementation of the appropriate interface.
Using a lambda, however, the same effect can be achieved much more concisely.
20
public class MyAnonymousInnerClass { public static void main(String[] args) { new Thread(new Runnable() { @Override public void run() {
System.out.println(“Hello!"); }}).start(); }}
public class MyAnonymousInnerClass { public static void main(String[] args) { new Thread(() -> System.out.println(“Hello!") ).start(); }}
Lambda Expression
21
Lambda Expression (Project Lambda) is one of the most exciting feature of Java 8.
Remember SAM type?In Java lambda expression is SAM type.
Lambda expressions let us express instances of single-method classes more compactly.
So what is lambda expression?
22
In mathematics and computing generally,
a lambda expression is a function.
For some or all
combinations of input values
An output value
It specifies
Lambda Syntax
23
The basic syntax of lambda is either
(parameters) -> expression
(parameters) -> { statements; }
or
Some examples
24
(int x, int y) -> x + y // takes two integers and returns their sum
(x, y) -> x – y // takes two numbers and returns their difference
() -> 42 // takes no values and returns 42
(String s) -> System.out.println(s) // takes a string, prints its value to the console, and returns nothing
x -> 2 * x // takes a number and returns the result of doubling it
c -> { int s = c.size(); c.clear(); return s; } // takes a collection, clears it, and returns its previous size
25
public class Main { @FunctionalInterface interface Action { void run(String s); } public void action(Action action){ action.run("Hello"); } public static void main(String[] args) { new Main().action( (String s) -> System.out.print("*" + s + "*") ); }} OUTPUT: *Hello*
26
E:\JAVA-8-EXAMPLES\LAMBDA>javap -p MainCompiled from "Main.java"public class Main { public Main(); public void action(Main$Action); public static void main(java.lang.String[]); private static void lambda$main$0(java.lang.String);}
There is a generated method lambda$0 in the decompiled class
© Unibet Group plc 2011
Method Reference
27
Sometimes a lambda expression does nothing but calls an existing method. In these cases it is clearer to refer to that existing method by name.
Method reference is a lambda expression for a method that already has a name.
Lets see an example....
28
public class Person { private Integer age;
public Person(Integer age) { this.setAge(age); }
public Integer getAge() { return age; }
private void setAge(Integer age) { this.age = age; }
public static int compareByAge(Person a, Person b) { return a.getAge().compareTo(b.getAge()); }
public static List<Person> createRoster() { List<Person> roster = new ArrayList<>(); roster.add(new Person(20)); roster.add(new Person(24)); roster.add(new Person(35)); return roster; }
@Override public String toString() { return "Person{ age=" + age + "}"; }}
29
public class WithoutMethodReferenceTest {
public static void main(String[] args) {
List<Person> roster = Person.createRoster();
Person[] rosterAsArray = roster.toArray(new Person[roster.size()]);
class PersonAgeComparator implements Comparator<Person> { public int compare(Person a, Person b) { return a.getAge().compareTo(b.getAge()); } }
// Without method reference Arrays.sort(rosterAsArray, new PersonAgeComparator());
for(int i=0; i<rosterAsArray.length; ++i){ System.out.println("" + rosterAsArray[i]); } }}
Without Method Reference
OUTPUT
Person{age=20}Person{age=24}Person{age=35}
30
Ah ....
PersonAgeComparator implements Comparator.
Comparator is a functional interface.
So lambda expression can be used
instead of defining and then creating a
new instance of a class that implements
Comparator<Person>.
31
public class WithLambdaExpressionTest {
public static void main(String[] args) { List<Person> roster = Person.createRoster();
Person[] rosterAsArray = roster.toArray(new Person[roster.size()]);
// With lambda expression Arrays.sort(rosterAsArray, (Person a, Person b) -> {return a.getAge().compareTo(b.getAge());} );
for(int i=0; i<rosterAsArray.length; ++i){ System.out.println("" + rosterAsArray[i]); } }}
With Lambda Expression
OUTPUT
Person{age=20}Person{age=24}Person{age=35}
32
However, this method to compare the ages of two Person instances already exists as Person.compareByAge
So we can invoke this method instead in the body of the lambda expression:
Arrays.sort(rosterAsArray, (a, b) -> Person.compareByAge(a, b) );
But we can do it more concisely using Method Reference.
public class MethodReferenceTest {
public static void main(String[] args) { List<Person> roster = Person.createRoster();
Person[] rosterAsArray = roster.toArray(new Person[roster.size()]);
// With method reference Arrays.sort(rosterAsArray, Person::compareByAge );
for(int i=0; i<rosterAsArray.length; ++i){ System.out.println("" + rosterAsArray[i]); } }}
33
With Method Reference
OUTPUT
Person{age=20}Person{age=24}Person{age=35}
34
There are four kinds of Method Reference
Reference to a static method
Reference to an instance method of a particular object
Reference to an instance method of an arbitrary object of a particular type
Reference to a constructor
ContainingClass::staticMethodName
ContainingObject::instanceMethodName
ContainingType::methodName
ClassName::new
35
Examples
Reference to a static method
Person::compareByAge
36
Examples (cont.)
Reference to an instance method of a particular object
class ComparisonProvider { public int compareByName(Person a, Person b) { return a.getName().compareTo(b.getName()); } public int compareByAge(Person a, Person b) { return a.getBirthday().compareTo(b.getBirthday()); } }
ComparisonProvider myCompProvider = new ComparisonProvider();
Arrays.sort(rosterAsArray, myCompProvider::compareByName);
37
Examples (cont.)
Reference to an instance method of an arbitrary object of a particular type
String[] stringArray = { "Barbara", "James", "Mary", "John", "Patricia", "Robert", "Michael", "Linda" };
Arrays.sort(stringArray, String::compareToIgnoreCase );
38
Examples (cont.)
Reference to a constructor
Set<Person> rosterSet = transferElements(roster, HashSet::new );
39
java.util.functionFunction<T, R> Takes a T as input, returns an R as output
Predicate<T> Takes a T as input, returns a boolean as output
Consumer<T> Takes a T as input, performs some action and doesn't return anything
Supplier<T> Does not take anything as input, return a T
And many more ---
40
java.util.stream
List<Book> books = …
//sequential version
Stream<Book> bookStream = books.stream();
//parallel version
Stream<Book> parallelBookStream = books.parallelStream();
Allows us to perform filter/map/reduce -like operations with the collections in Java 8.
Thank you.