Java Stream API & Functional Interface

Java Stream API & Functional Interface

Stream API

Stream API was added in JAVA 8 & it has provided a much better way of working with Collections. It provides a way to write Readable, Concise & Declarative code with the help of Functional Interface.

Stream API provides access to the Collections Data, which can be processed Sequentially or Parallel. Stream provides plenty of methods to perform operations on data which can produce a Result or Side-Effects.

Commonly used Stream Methods

  • count(): Count of elements in the Stream
  • distinct(): Returns a Stream consisting of Distinct Elements. It uses equals() method for comparison.
  • filter(Predicate): It takes in a Predicate Functional Interface, using which it returns a new Stream which consists of the elements that satisfied the predicate.
  • map(Function): It takes in a Function Functional Interface, using which it transforms each element in the Stream & returns them as a new Stream.
  • reduce(): It takes in a BinaryOperator Functional Interface using which the Steam is reduced into a Single Element which is then returned.
  • forEach(): It takes in a Consumer Functional Interface to which stream passes each element to perform the specified operations, it doesn't return anything. It's also known as an Internal Loop.
  • & many more...

I've explained Functional Interface Later in the Article.

How to use Stream API

In order to use Stream, we need a Collection or Array.

import java.util.Arrays
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Predicate;

public class D2 {
? ? public static void main(String[] args) {
? ? ? ? List<Integer> nums = Arrays.asList(1, -4, 5, 2, 6, 9);
        
? ? ? ? Predicate<Integer> isEven = new Predicate<Integer>() {
? ? ? ? ? ? @Override
? ? ? ? ? ? public boolean test(Integer t) {
? ? ? ? ? ? ? ? return t % 2 == 0;
? ? ? ? ? ? }
? ? ? ? };

? ? ? ? Consumer<Integer> print = new Consumer<Integer>() {
? ? ? ? ? ? @Override
? ? ? ? ? ? public void accept(Integer t) {
? ? ? ? ? ? ? ? System.out.println(t);
? ? ? ? ? ? }
? ? ? ? };

? ? ? ? nums.stream().filter(isEven).forEach(print);
? ? }
}        

In this code, I'm Printing All the Even Numbers from a List, using Stream API & Functional Interface (more on this later).

  1. Initialize a List with a few Random Numbers.
  2. I'm creating a Predicate Functional Interface which determined if the provided input is even.
  3. I'm creating a Consumer Functional Interface which prints out the input.
  4. Finally, I'm Creating a stream nums.stream()
  5. I used the filter method, which takes in a Predicate to Filter out the Elements from the original Stream & returns a new Stream.
  6. With the returned stream, I'm using forEach method, that takes in a Consumer using which I'm printing each element.

Functional Interface

Now, the Code above seems like a really Verbose way of performing a simple task due to the way we have to define Functional Interfaces. But Java has a much better way of dealing with this issue. But before that we need to understand Functional Interface.

Functional Interface is used to represent & enforce SAM, i.e., Single Abstract Method. It's an interface that has only one Method, this empowers Functional Programming in JAVA & is at the Heart of Stream API.

The code above is a nice example of how to use Functional Interfaces by defining an Anonymous Inner Class.

Common Functional Interfaces

  • Predicate<T>: It takes in an argument of type T & returns a boolean. Used in stream.filter.
  • Function<T, R>: It takes in an argument of type T & returns a result of type R. Used in stream.map.
  • Consumer<T>: It takes in an argument of type T & performs some action on it. Doesn't return anything. Used in stream.forEach
  • & many more...

Lambda Expressions

The code in the First Section is a good example of how to use the Functional Interface, but as I pointed out before, it's a bit Verbose. To solve this problem, JAVA provides a better syntax known as the Lambda Expression.

Lambda Expression just replaces the Functional Interfaces definition into just a few lines of code.

// Normal Definition
Predicate<Integer> isEven = new Predicate<Integer>() {
? ? @Override
? ? public boolean test(Integer t) {
? ? ? ? return t % 2 == 0;
? ? }
};
// Lambda Expression
Predicate<Integer> isEven = n -> {
? ? return n % 2 == 0;
};
// Lamdba Expression with Implicit Return
Predicate<Integer> isEven = n -> n % 2 == 0;        

In the code above, we are replacing the entire Inner Class Definition with just a few lines of code. Both the Lambda Expressions are directly defining the test method that takes in an argument n.

In the first Lambda, I'm explicitly returning the result of a boolean expression.

But in Lambda Expression it is possible to omit the Code Block & return as well if there is only one statement. Hence, in the second Lambda, I'm just writing the boolean expression that will implicitly get returned.

Even Filter using Lambda

Here is a re-implementation of Stream API Example using Lambda

import java.util.Arrays
import java.util.List;

public class D2 {
? ? public static void main(String[] args) {
? ? ? ? List<Integer> nums = Arrays.asList(1, -4, 5, 2, 6, 9);
? ? ? ? nums.stream()
? ? ? ? ? ? ? ? .filter(n -> n % 2 == 0)
? ? ? ? ? ? ? ? .forEach(n -> System.out.println(n));
? ? }
}        

Now, with the help of Lambda Expressions, I'm able to perform the same task of Printing all the Even elements in a List using just 3 Lines of Code.

Day 2 Challenge

Challenge

Continue development of Product Management Project & Implement the Following:

  • Search Product by Place
  • Get Products whose Warranty is Expired
  • Implement using Stream API

Solution:

GitHub Repo?README includes the Explanation of My Solutions.

Thank You, Navin Reddy , for the 10-Day Challenge.

#10daychallenge #day2 #java #programming #learning #functionalprogramming

要查看或添加评论,请登录

Shivangam Soni的更多文章

  • Modern JAVA Features

    Modern JAVA Features

    Ever since JAVA 8 there have been plenty of Regular changes to the Language. Many of these Changes are targeted towards…

  • Java Annotation: What, Why & How?

    Java Annotation: What, Why & How?

    Java Annotation Java Annotations are a way for us to provide Metadata or Additional Instructions about the Code…

    1 条评论
  • Java Reflection API & How Spring uses Reflection.

    Java Reflection API & How Spring uses Reflection.

    Reflection API Java Reflection API allows us to examine a class's behavior at Run-Time. It also allows us to manipulate…

  • Spring Data JPA

    Spring Data JPA

    JPA Java Persistence API (JPA) is a Java Specification for Object Relational Mapping (ORM). It provides a high-level…

  • Recursion & Memoization

    Recursion & Memoization

    Iteration I think it's important to understand Iteration to fully understand Recursion. Iteration is a Programming…

    2 条评论

社区洞察

其他会员也浏览了