java 8 lambda expressions
Post on 07-Aug-2015
162 Views
Preview:
TRANSCRIPT
LAMBDA EXPRESSIONSJAVA 8
Prasad Gamini
INTERFACES IN JAVA 8
• In JAVA 8, the interface body can contain • Abstract methods• Static methods• Default methods
• Example
public interface SampleIface { public void process(); public static void print(){ System.out.println("Static Method In Interface"); } public default void apply(){ System.out.println("Default Metod In Interface"); }}
FUNCTIONAL INTERFACE
• java.lang.Runnable, java.awt.event.ActionListener, java.util.Comparator, java.util.concurrent.Callable … etc ;
• There is some common feature among the stated interfaces and that feature is they have only one method declared in their interface definition
• These interfaces are called Single Abstract Method interfaces (SAM Interfaces)
• With Java 8 the same concept of SAM interfaces is recreated and are called Functional interfaces
• There’s an annotation introduced- @FunctionalInterface which can be used for compiler level errors when the interface you have annotated is not a valid Functional Interface.
EXAMPLE@FunctionalInterfacepublic interface Predicate<T> {
boolean test(T t);
default Predicate<T> and(Predicate<? super T> other) { ------SOME CODE-------- }
default Predicate<T> negate() { ------SOME CODE--------
}
default Predicate<T> or(Predicate<? super T> other) { ------SOME CODE--------
}
static <T> Predicate<T> isEqual(Object targetRef) { ------SOME CODE--------
}}
ANONYMOUS INNER CLASSES
• An interface that contains only one method, then the syntax of anonymous classes may seem unwieldy and unclear.
• We're usually trying to pass functionality as an argument to another method, such as what action should be taken when someone clicks a button.
okButton.addActionListener(new ActionListener() {
@Override public void actionPerformed(ActionEvent e) { System.out.println("OK Button Clicked"); }});
LAMBDA
• Lambda expressions enable us to treat functionality as method argument, or code as data
• Lambda expressions let us express instances of single-method classes more compactly.
• A lambda expression is composed of three parts.
Argument List Arrow Token Body
(int x, int y) -> x + y
okButton.addActionListener(new ActionListener() {
@Override public void actionPerformed(ActionEvent e) { System.out.println("OK Button Clicked"); }});
okButton.addActionListener((ActionEvent e) -> { System.out.println("OK Button Clicked - 2");});okButton.addActionListener( (ActionEvent e) -> System.out.println("OK Button Clicked"));
okButton.addActionListener(e -> System.out.println("OK Button Clicked"));
Equivalent Lambda expression
EXAMPLE
EXAMPLE
new Thread(new Runnable() { @Override public void run() { for (int i=1;i<=10;i++){ System.out.println("i = " + i); } }}).start();
Equivalent Lambda expression
new Thread(() -> { for (int i=1;i<=10;i++){ System.out.println("i = " + i); }}).start();
EXAMPLE
Collections.sort(employeeList, new Comparator<Employee>() {
@Override public int compare(Employee e1, Employee e2) { return e1.getEmpName().compareTo(e2.getEmpName()); }});
Equivalent Lambda expression
Collections.sort(employeeList, (e1, e2) ->
e1.getEmpName().compareTo(e2.getEmpName()));
EXAMPLE
Collections.sort(employeeList, (e1, e2) -> e1.getEmpName().compareTo(e2.getEmpName()));
Collections.sort(employeeList,(Employee e1, Employee e2) ->
e1.getEmpName().compareTo(e2.getEmpName()));
Collections.sort(employeeList, (e1, e2) -> { return e1.getEmpName().compareTo(e2.getEmpName());});
Collections.sort(employeeList, (Employee e1, Employee e2) -> { return e1.getEmpName().compareTo(e2.getEmpName());});
METHOD REFERENCES
• Sometimes a lambda expression does nothing but call an existing method
• In those cases, it's often clearer to refer to the existing method by name
• Method references enable you to do this; they are compact, easy-to-read lambda expressions for methods that already have a name.
• Different kinds of method references:
Kind Example
Reference to a static method ContainingClass::staticMethodName
Reference to an instance method of a particular object containingObject::instanceMethodName
Reference to a constructor ClassName::new
REFERENCE TO A STATIC METHODpublic class Person { private String firstName; private String lastName; private Calendar birthday;
//GETTERS & SETTERS public static int compareByAge(Person a, Person b) { return a.getBirthday().compareTo(b.getBirthday()); }}
Collections.sort(personList, (p1,p2) -> Person.compareByAge(p1, p2));
Lambda expression
Equivalent Method Reference
Collections.sort(personList, Person::compareByAge);
REFERENCE TO AN INSTANCE METHOD
public class ComparisonProvider { public int compareByName(Person a, Person b) { return a.getFirstName().compareTo(b.getFirstName()); } public int compareByAge(Person a, Person b) { return a.getBirthday().compareTo(b.getBirthday()); }}ComparisonProvider comparisonProvider = new ComparisonProvider();
Collections.sort(personList, (p1,p2) -> comparisonProvider.compareByName(p1, p2));
Lambda expression
Collections.sort(personList, comparisonProvider::compareByName);
Equivalent Method Reference
REFERENCE TO A CONSTRUCTOR
public static void transfer(Map<String, String> source, Supplier<Map<String, String>> mapSupplier){ // code to transfer}
Anonymous Inner Class transfer(src, new Supplier<Map<String, String>>() { @Override public Map<String, String> get() { return new HashMap<>(); }});
Lambda expressiontransfer(src, () -> new HashMap<>());
Equivalent Method Referencetransfer(src, HashMap::new);
AGGREGATE OPERATIONS IN COLLECTIONS
• Streams• A stream is a sequence of elements. Unlike a collection, it is not a data
structure that stores elements.
• Pipelines• A pipeline is a sequence of aggregate operations.• PIPELINE contains the following
• A Source• Zero or more intermediate operations• A terminal operation
EXAMPLEList<Employee> employeeList = new ArrayList<>();//Add elements into employee list.
employeeList.stream().filter(employee -> employee.getGender() == Person.Sex.FEMALE).forEach(employee -> System.out.println(employee));
int totalAge = employeeList .stream() .mapToInt(Person::getAge) .sum();
double average = employeeList .stream() .filter(p -> p.getGender() == Person.Sex.MALE) .mapToInt(Person::getAge) .average() .getAsDouble();
Questions
top related