Presentation is loading. Please wait.

Presentation is loading. Please wait.

„Lambda expressions, Optional”

Similar presentations


Presentation on theme: "„Lambda expressions, Optional”"— Presentation transcript:

1 „Lambda expressions, Optional”

2 Let’s see this on example…
Lambda expression Lambda expressions, Optional New in Java 8. Java lambda expression is a function which can be created without belonging to any class. Java lambda expression can be passed around as if it was an object and executed on demand. Java lambda expressions are commonly used to implement simple event listeners / callbacks, or in functional programming (see Java Streams API) Let’s see this on example…

3 Lambda expression as a single method interface
Lambda expressions, Optional Let's look for the classic implementation of a listener in Java 7. This Java interface defines a single method which is called whenever the state changes (in whatever is being observed).

4 Lambda expression as a single method interface
Lambda expressions, Optional In Java 7 you would have to implement this interface in order to listen for state changes. Imagine you have a class called StateOwner which can register state event listeners. Here is an example:

5 Lambda expression as a single method interface
Lambda expressions, Optional Let’s add implementation of event listener:

6 Lambda expression as a single method interface
Lambda expressions, Optional Rewrite it in Java 8 using lambda expression: Below statement is out lambda expression:

7 Lambda expression as a single method interface
Lambda expressions, Optional The lambda expression is matched against the parameter type of the addStateListener() method's parameter. If the lambda expression matches the parameter type (in this case the StateChangeListener interface), then the lambda expression is turned into a function that implements the same interface as that parameter. Java lambda expressions can only be used where the type they are matched against is a single method interface. In the example above, a lambda expression is used as parameter where the parameter type was the StateChangeListener interface. This interface only has a single method. Thus, the lambda expression is matched successfully against that interface.

8 Lambda expression- type inference
Lambda expressions, Optional With lambda expressions the type can often be inferred from the surrounding code. For instance, the interface type of the parameter can be inferred from the method declaration of the addStateListener() method (the single method on the StateChangeListener interface). This is called type inference. The compiler infers the type of a parameter by looking elsewhere for the type - in this case the method definition. In the lambda expression the parameter types can often be inferred too. In the example, the compiler can infer their type from the onStateChange() method declaration. Thus, the type of the parameters oldState and newState are inferred from the method declaration of the onStateChange() method.

9 Lambda expression- parameters
Lambda expressions, Optional Since Java lambda expressions are effectively just methods, lambda expressions can take parameters just like methods. When a lambda expression takes a single parameter, you can also omit the parentheses, like this:

10 Lambda expression- parameters
Lambda expressions, Optional If the method you match your Java lambda expression against takes multiple parameters, the parameters need to be listed inside parentheses.

11 Lambda expression- parameter type
Lambda expressions, Optional Specifying parameter types for a lambda expression may sometimes be necessary if the compiler cannot infer the parameter types from the functional interface method the lambda is matching. Don't worry, the compiler will tell you when that is the case.

12 Lambda expression- body
Lambda expressions, Optional The body of a lambda expression, and thus the body of the function / method it represents, is specified to the right of the -> in the lambda declaration. If your lambda expression needs to consist of multiple lines, you can enclose the lambda function body inside the { } bracket.

13 Lambda expression- returning value
Lambda expressions, Optional You can return values from Java lambda expressions, just like you can from a method. You just add a return statement to the lambda function body. In case all your lambda expression is doing is to calculate a return value and return it, you can specify the return value in a shorter way.

14 Lambda expression- an object
Lambda expressions, Optional A Java lambda expression is essentially an object. You can assign a lambda expression to a variable and pass it around, like you do with any other object.

15 Lambda expression as a single method interface- major difference
Lambda expressions, Optional Even though lambda expressions are close to anonymous interface implementations, there are a few differences that are worth noting. The major difference is, that an anonymous interface implementation can have state (member variables) whereas a lambda expression cannot. Look at this interface:

16 Lambda expression as a single method interface- major difference
Lambda expressions, Optional This interface can be implemented using an anonymous interface implementation. This anonymous MyEventConsumer implementation can have its own internal state.

17 Lambda expression as a single method interface- major difference
Lambda expressions, Optional Notice how the anonymous MyEventConsumer implementation now has a field named eventCount. A lambda expression cannot have such fields. A lambda expression is thus said to be stateless.

18 Lambda expression- variable capture
Lambda expressions, Optional A Java lambda expression is capable of accessing variables declared outside the lambda function body under certain circumstances. Java lambdas can capture the following types of variables: Local variables Instance variables Static variables

19 Lambda expression- local variable
Lambda expressions, Optional The lambda body references the local variable myString which is declared outside the lambda body. This is possible if, and only if, the variable being references is "effectively final", meaning it does not change its value after being assigned. If the myString variable had its value changed later, the compiler would complain about the reference to it from inside the lambda body.

20 Lambda expression- instance variable
Lambda expressions, Optional This captures the name instance variable of the enclosing EventConsumerImpl object. It is even possible to change the value of the instance variable after its capture - and the value will be reflected inside the lambda.

21 Lambda expression- static variable
Lambda expressions, Optional This is not surprising, as static variables are reachable from everywhere in a Java application, provided the static variable is accessible (packaged scoped or public).

22 Lambda expression- functional interface
Lambda expressions, Optional Functional interface is any interface that has one abstract method and only those can be implemented by lambda expression. There are few of them in Java: Function<T, R> Consumer<T> Predicate<T> Supplier<T> UnaryOperator<T> Whenever you see them in method parameters, you can use lambda expression.

23 Lambda expression- functional interface
Lambda expressions, Optional Examples are in java.util.Stream

24 Optional Lambda expressions, Optional Java 8 has introduced a new class Optional in java.util package. It is used to represent a value is present or absent. The main advantage of this new construct is that no more too many null checks and NullPointerException. It avoids any runtime NullPointerExceptions and supports us in developing clean and neat Java APIs or Applications. Like Collections and arrays, it is also a Container to hold at most one value.

25 Optional- creating object
Lambda expressions, Optional There are several ways of creating Optional objects. To create an empty Optional object, we simply need to use its empty static method: We can also create an Optional object with the static method of:

26 Optional- creating object
Lambda expressions, Optional However, the argument passed to the of() method can’t be null. Otherwise, we’ll get a NullPointerException: But, in case we expect some null values, we can use the ofNullable() method:

27 Optional- checking value
Lambda expressions, Optional When we have an Optional object returned from a method or created by us, we can check if there is a value in it or not with the isPresent() method: This method returns true if the wrapped value is not null.

28 Optional- checking value
Lambda expressions, Optional The ifPresent() method enables us to run some code on the wrapped value if it’s found to be non-null. Before Optional, we’d do: Let us now look at how the above code could be refactored in Java 8.

29 Optional- checking value
Lambda expressions, Optional Do you remember functional interface? ifPresent method is using it:

30 Optional- returning value
Lambda expressions, Optional There are several ways of returning values from Optional objects. The get() method:

31 Optional- returning value
Lambda expressions, Optional The orElse() method is used to retrieve the value wrapped inside an Optional instance. It takes one parameter which acts as a default value. The orElse() method returns the wrapped value if it’s present and its argument otherwise:

32 Optional- returning value
Lambda expressions, Optional The orElseGet() method is similar to orElse(). However, instead of taking a value to return if the Optional value is not present, it takes a supplier functional interface which is invoked and returns the value of the invocation:

33 Optional- returning value
Lambda expressions, Optional The orElseThrow() method follows from orElse() and orElseGet() and adds a new approach for handling an absent value. Instead of returning a default value when the wrapped value is not present, it throws an exception:

34 Optional- difference between orElse and orElseGet
Lambda expressions, Optional The difference between orElse() and orElseGet() is not clear. As a matter of fact, these two methods give the impression that they overlap each other in functionality. However, there’s a subtle but very important difference between the two which can affect the performance of our code drastically if not well understood. Let’s create a method called getMyDefault() in the test class which takes no arguments and returns a default value:

35 Optional- difference between orElse and orElseGet
Lambda expressions, Optional Let’s see two tests and observe their side effects to establish both where orElse() and orElseGet() overlap and where they differ:

36 Optional- difference between orElse and orElseGet
Lambda expressions, Optional We wrap a null text inside an Optional object and we attempt to get the wrapped value using each of the two approaches. The side effect is as below: The getMyDefault() method is called in each case. It so happens that when the wrapped value is not present, then both orElse() and orElseGet() work exactly the same way.

37 Optional- difference between orElse and orElseGet
Lambda expressions, Optional Now let’s run another test where the value is present and ideally, the default value should not even be created:

38 Optional- difference between orElse and orElseGet
Lambda expressions, Optional We are no longer wrapping a null value and the rest of the code remains the same. Now let’s take a look at the side effect of running this code:

39 Optional- difference between orElse and orElseGet
Lambda expressions, Optional Notice that when using orElseGet() to retrieve the wrapped value, the getMyDefault() method is not even invoked since the contained value is present. However, when using orElse(), whether the wrapped value is present or not, the default object is created. So in this case, we have just created one redundant object that is never used. In this simple example, there is no significant cost to creating a default object, as the JVM knows how to deal with such. However, when a method such as getMyDefault() has to make a web service call or even query a database, then the cost becomes very obvious.

40 Optional- filter Lambda expressions, Optional We can run an inline test on our wrapped value with the filter method. It takes a predicate as an argument and returns an Optional object. If the wrapped value passes testing by the predicate, then the Optional is returned as-is. However, if the predicate returns false, then it will return an empty Optional:

41 Optional- map Lambda expressions, Optional We can use a similar syntax to transform the Optional value with the map() method:

42 Optional- map Lambda expressions, Optional In this example, we wrap a list of strings inside an Optional object and use its map method to perform an action on the contained list. The action we perform is to retrieve the size of the list. The map method returns the result of the computation wrapped inside Optional. We then have to call an appropriate method on the returned Optional to retrieve its value.

43 We can chain map and filter together to do something more powerful:
Optional- chaining Lambda expressions, Optional We can chain map and filter together to do something more powerful:

44 Let’s see this on example:
Optional- flatMap Lambda expressions, Optional Just like the map() method, we also have the flatMap() method as an alternative for transforming values. The difference is that map transforms values only when they are unwrapped whereas flatMap takes a wrapped value and unwraps it before transforming it. Let’s see this on example:

45 Optional- flatMap Lambda expressions, Optional We would normally create such an object and wrap it in an Optional object just like we did with String. Alternatively, it can be returned to us by another method call:

46 Optional- flatMap Lambda expressions, Optional Notice now that when we wrap a Person object, it will contain nested Optional instances:

47 Optional- flatMap Lambda expressions, Optional Here, we’re trying to retrieve the name attribute of the Person object to perform an assertion. Note how we achieve this with map() method in the third statement and then notice how we do the same with flatMap() method afterwards.

48 Optional- where Lambda expressions, Optional Finally, let’s see a tempting, however dangerous, way to use Optionals: passing an Optional parameter to a method. Imagine we have a list of Person and we want a method to search through that list for people having a given name. Also, we would like that method to match entries with at least a certain age, if it’s specified. With this parameter being optional, we come with this method:

49 Then, we release our method and another developer tries to use it:
Optional- where Lambda expressions, Optional Then, we release our method and another developer tries to use it: Now, the developer executes its code and gets a NullPointerException. There we are, having to null check our optional parameter, which defeats our initial purpose in wanting to avoid this kind of situation.

50 Here are some possibilities we could have done to handle it better:
Optional- where Lambda expressions, Optional Here are some possibilities we could have done to handle it better:

51 Optional- where Lambda expressions, Optional There, the parameter’s still optional, but we handle it in only one check. Another possibility would have been to create two overloaded methods:

52 Optional- where Lambda expressions, Optional That way we offer a clear API with two methods doing different things (though they share the implementation). So, there are solutions to avoid using Optionals as method parameters. The intent of Java when releasing Optional was to use it as a return type, thus indicating that a method could return an empty value. As a matter of fact, the practice of using Optional as a method parameter is even discouraged by some code inspectors.


Download ppt "„Lambda expressions, Optional”"

Similar presentations


Ads by Google