Java 8. Features

Содержание

Слайд 2

Agenda

Anonymous classes
Default methods in interfaces
Lambda expressions
Functional Interfaces
Method and Constructor References
Lambda Scopes
Accessing local

Agenda Anonymous classes Default methods in interfaces Lambda expressions Functional Interfaces Method
variables
Accessing fields and static variables
Accessing Default Interface Methods
Built-in Functional Interfaces
Optional interface

Слайд 3

Anonymous Inner Classes

Anonymous inner class – class that has no name and

Anonymous Inner Classes Anonymous inner class – class that has no name
is used if you need to create a single instance of the class.
Any parameters needed to create an anonymous object class, are given in parentheses following name supertype:

new Supertype(list_of_parameters) {
// body
};

Слайд 4

people.sort( new Comparator() {
@Override public int compare(Person p1, Person p2)

people.sort( new Comparator () { @Override public int compare(Person p1, Person p2)
{ return p1.getName().compareTo(p2.getName()); }
} );

Anonymous Inner Class - Example
new creates an object
Comparator( ... ) begins definition of anonymous class
Similar to
Brace ( { ) begins class definition

public class NameComparator implements Comparator()

Слайд 5

Default Methods for Interfaces

Java 8 enables us to add non-abstract method implementations

Default Methods for Interfaces Java 8 enables us to add non-abstract method
to interfaces by utilizing the default keyword. This feature is also known as Extension Methods.
For example:

public interface Formula { double calculate(int a); default double sqrt(int a) { return Math.sqrt(a); } }

Слайд 6

Default Methods for Interfaces

Besides the abstract method calculate the interface Formula also defines the

Default Methods for Interfaces Besides the abstract method calculate the interface Formula
default method sqrt.
Concrete classes only have to implement the abstract method calculate.
The default method sqrt can be used out of the box.

Formula formula = new Formula() { @Override public double calculate(int a) { return sqrt(a * 100); } }; formula.calculate(100); // 100.0 formula.sqrt(16); // 4.0

Слайд 7

Default Methods for Interfaces

The formula is implemented as an anonymous object.
As

Default Methods for Interfaces The formula is implemented as an anonymous object.
we'll see in the next section, there's a much nicer way of implementing single method objects in Java 8.

formula.calculate(100); // 100.0 formula.sqrt(16); // 4.0

Слайд 8

Private methods for Interfaces

From Java SE 9 on-wards, we can write private

Private methods for Interfaces From Java SE 9 on-wards, we can write
and private static methods too in an interface using private keyword.

public interface Formula { private int pow(int a, int b) { return (int)Math.pow(a, b); } private static double getPI() { return Math.PI; } default double circleArea(int radius) { return Formula.getPI() * pow(radius, 2); } }

Слайд 9

Lambda expressions

Sort a list of strings in prior versions of Java:

List names

Lambda expressions Sort a list of strings in prior versions of Java:
= Arrays
.asList("Ivan", "Olexandra", "Anton", "Polina"); Collections.sort(names, new Comparator() { @Override public int compare(String a, String b) { return b.compareTo(a); } });

Слайд 10

Lambda expressions

The static utility method Collections.sort accepts a list and a comparator

Lambda expressions The static utility method Collections.sort accepts a list and a
in order to sort the elements of the given list.
You often find yourself creating anonymous comparators and pass them to the sort method.

Слайд 11

Lambda expressions

In Java 8 comes with a much shorter syntax, lambda expressions

Collections.sort(names, (String

Lambda expressions In Java 8 comes with a much shorter syntax, lambda
a, String b) -> { return b.compareTo(a); } );

Слайд 12

Lambda expressions

As you can see the code is much shorter and easier

Lambda expressions As you can see the code is much shorter and
to read. But it gets even shorter:
For one line method bodies you can skip both the braces { } and the return keyword. But it gets even more shorter:
The java compiler is aware of the parameter types so you can skip them as well.

Collections.sort(names, (String a, String b)
-> b.compareTo(a));

Collections.sort(names, (a, b) -> b.compareTo(a));

Слайд 13

Functional Interfaces

How does lambda expressions fit into Javas type system? Each lambda

Functional Interfaces How does lambda expressions fit into Javas type system? Each
corresponds to a given type, specified by an interface. A so called functional interface must contain exactly one abstract method declaration.
Each lambda expression of that type will be matched to this abstract method.
To ensure that your interface meet the requirements, you should add the @FunctionalInterface annotation. The compiler is aware of this annotation and throws a compiler error as soon as you try to add a second abstract method declaration to the interface.

Слайд 14

Functional Interfaces

For example,
Keep in mind that the code is also valid if

Functional Interfaces For example, Keep in mind that the code is also
the @FunctionalInterface annotation would be omitted.

@FunctionalInterface interface Converter { T convert(F from); }
Converter converter = (from) -> Integer.valueOf(from);
Integer converted = converter.convert("123");
System.out.println(converted); // 123

Слайд 15

Method and Constructor References

The above example code can be further simplified by

Method and Constructor References The above example code can be further simplified
utilizing static method references:
Java 8 enables you to pass references to methods or constructors via the :: expression. The above example shows how to reference a static method.

Converter converter = Integer::valueOf;
Integer converted = converter.convert("123");
System.out.println(converted); // 123

Слайд 16

Method and Constructor References

We can also reference instance methods:

class StringUtil { char

Method and Constructor References We can also reference instance methods: class StringUtil
startsWith(String s) { return Character.valueOf(s.charAt(0)); } } StringUtil strUtil = new StringUtil(); Converter converter = strUtil::startsWith; char converted = converter.convert("Java"); System.out.println(converted); // "J"

Слайд 17

Method and Constructor References

Let's see how the :: expression works for constructors.

class Person

Method and Constructor References Let's see how the :: expression works for
{
String firstName; String lastName; Person() { } Person(String firstName, String lastName) { this.firstName = firstName; this.lastName = lastName; } }

Слайд 18

Method and Constructor References

Next we specify a person factory interface to be

Method and Constructor References Next we specify a person factory interface to
used for creating new persons:
Instead of implementing the factory manually, we glue everything together via constructor references:
We create a reference to the Person constructor via  Person::new. The compiler automatically chooses the right constructor by matching the method signature create.

interface PersonFactory

{ P create(String firstName, String lastName); }

PersonFactory personFactory = Person::new;
Person person = personFactory.create("Peter", "Parker");

Слайд 19

Lambda Scopes

Accessing outer scope variables from lambda expressions is very similar to

Lambda Scopes Accessing outer scope variables from lambda expressions is very similar
anonymous objects. You can now access “effectively final” variables from outer scope as well as instance and static fields.
Lets consider
Accessing local variables
Accessing fields and static variables
Accessing Default Interface Methods

Слайд 20

Accessing local variables

We can read final local variables from outer scope of

Accessing local variables We can read final local variables from outer scope
lambda expressions:
As well as in anonymous objects the variable num is not required to be final. This code is also valid:
However num must be effectively final for the code to compile. The following code does not compile:

final int num = 1; Converter stringConverter = (from) -> String.valueOf(from + num); stringConverter.convert(2); //3

int num = 1; Converter stringConverter = (from) -> String.valueOf(from + num); stringConverter.convert(2); //3

int num = 1; Converter stringConverter = (from) -> String.valueOf(from + num); num = 3;

Слайд 21

Accessing fields and static variables

We also have both read and write access

Accessing fields and static variables We also have both read and write
to instance fields and static variables from within lambda expressions.

class Test { static int outerStaticNum; int outerNum; void testScopes() { Converter stringConverter1 = (from) -> { outerNum = 23; return String.valueOf(from); }; Converter stringConverter2 = (from) -> { outerStaticNum = 72; return String.valueOf(from); }; } }

Слайд 22

Accessing Default Interface Methods

Interface Formula defines a default method sqrt which can be accessed from

Accessing Default Interface Methods Interface Formula defines a default method sqrt which
each formula instance including anonymous objects.
But, default methods cannot be accessed from within lambda expressions. The following code does not compile:

public interface Formula { double calculate(int a); default double sqrt(int a) { return Math.sqrt(a); } }

Formula formula = (a) -> sqrt(a * 100);

Слайд 23

Built-in Functional Interfaces

The JDK 1.8 API contains many built-in functional interfaces. Some

Built-in Functional Interfaces The JDK 1.8 API contains many built-in functional interfaces.
of them are well known from older versions of Java like Comparator or Runnable.
Those existing interfaces are extended to enable Lambda support via the @FunctionalInterface annotation.
But the Java 8 API is also full of new functional interfaces to make your life easier which contains in package java.util.function

Слайд 24

Predicates

Predicates are boolean-valued functions of one argument. The interface contains various default

Predicates Predicates are boolean-valued functions of one argument. The interface contains various
methods for composing predicates to complex logical terms (and, or, negate)

public interface Predicate { boolean test(T t);
}

Слайд 25

Functions

Functions accept one argument and produce result. Default methods can be used

Functions Functions accept one argument and produce result. Default methods can be
to chain multiple functions together(compose, andThen).

public interface Function { R apply(T t);
}

Слайд 26

Suppliers

Suppliers produce a result of a given generic type. Unlike Functions, Suppliers

Suppliers Suppliers produce a result of a given generic type. Unlike Functions,
don't accept arguments.

public interface Supplier { T get(); }

Слайд 27

Consumers

Consumers represents operations to be performed on a single input argument.

public interface

Consumers Consumers represents operations to be performed on a single input argument.
Consumer { void accept(T t);
}

Слайд 28

Optionals

Optionals are not functional interfaces, instead it's a nifty utility to prevent

Optionals Optionals are not functional interfaces, instead it's a nifty utility to
NullPointerException.
Optional is a simple container for a value which may be null or non-null.
Think of a method which may return a non-null result but sometimes return nothing. Instead of returning null you return an Optional in Java 8.

Optional optional = Optional.of("Java"); optional.isPresent(); // true optional.get(); // "Java" optional.orElse("fallback"); // "Java" optional.ifPresent((s) -> System.out.println(s.charAt(0))); // "J"