Skip to main content

Java Functional Interface

1. What is Functional Interface

An interface with only one abstract method is called Functional Interface.

Pre Java 8, there was no concept of Functional Interface. However, interfaces like Comparator and Runnable have only one abstract method. Hence they fell into the Functional Interface category in Java 8 unintentionally.

2. Example

2.1 getSellingPrice method snippet from App.Java

package org.geekmj.java8;

public class App {

	public static void main(String[] args) {
		// 
	}

	private static float getSellingPrice(float cost, float couponDiscount, DiscounterFunctionalInterface discounter) {
		return cost - couponDiscount - discounter.discount(cost);
	}
}

Here, we have a method getSellingPrice, with three arguments cost, couponDiscount and discounter. discounter is of type DiscounterFunctionalInterface. It calculates the selling price for an item.

2.2 DiscounterFunctionalInterface.java

package org.geekmj.java8;

@FunctionalInterface
public interface DiscounterFunctionalInterface {
	public float discount(float cost);
}

Here, DiscounterFunctionalInterface is a functional interface with one abstract method discount. The implementation of this method will calculate the discount for a given cost applying discount percentage.

2.3 App.java

package org.geekmj.java8;

public class App {

	public static void main(String[] args) {

		/* Discount for Cloth is 10% of cost */

		System.out.println("Selling Price of Cloth Prices 200 after discount is " + getSellingPrice(200f, 0f, cost -> (cost * 10) / 100));

		/* Discount for Book is 5% of cost */

		System.out.println("Selling Price of Book Priced 150 after discount is " + getSellingPrice(150f, 10f, cost -> (cost * 5) / 100));
	}

	private static float getSellingPrice(float cost, float couponDiscount, DiscounterFunctionalInterface discounter) {
		return cost - couponDiscount - discounter.discount(cost);
	}
}

Here, in the main method, you had made a call to getSellingPrice twice. You can see how we passed two different implementations of DiscounterFunctionalInterface using lambda expressions.

getSellingPrice(200f, 0f, cost -> (cost * 10) / 100)
getSellingPrice(150f, 10f, cost -> (cost * 5) / 100)

The compiler map the lambda expression signature with the discount method in DiscounterFunctionalInterface. It happens so because we have only one abstract method in DiscounterFunctionalInterface.

The above sample is also an example of Behaviour Parameterization or Execute Around Pattern using Lambda Expression.

3. Can you have multiple methods in Functional Interface?

Yes, you can have multiple methods in a Functional Interface. However, they can only be default methods.

4. Why it is Required?

Lambda Expression in Java 8 provides the ability to define a concise inline function that we can pass around.

In Java, we can pass Class and Primitive data types as an argument to a method.

Hence Java 8 Designer decided to introduce Functional Interface. Which will have only one abstract method. It allows the concise implementation of a Functional interface using Lambda expression. It further allowing lambda expression to pass around easily to methods.

Functional Interface is a simple design choice to represent Lambda Expression as an instance.

5. Function Descriptor

The description of the signature of the Lambda Expression is the same as the signature of the Functional Interface abstract method. Hence this abstract method is also called Function Descriptor.

6. @FunctionalInterface annotation

Most of the Functional Interfaces in Java 8 are annotated with @FunctionalInterface. However, it is not mandatory. But it is considered a good practice to use @FunctionalInterface.

7. Inbuilt Functional Interfaces in Java

In Java 8, we have several inbuilt Functional Interfaces that can be used by Lambda Expression readily. We will learn about them in another tutorial guide.

8. Source Code

Source code is available on GitHub for clone and download.

Comments

Popular posts from this blog

Working with request header in Jersey (JAX-RS) guide

In the  previous post , we talked about, how to get parameters and their values from the request query string. In this guide learn how to get request header values in Jersey (JAX-RS) based application. We had tested or used the following tools and technologies in this project: Jersey (v 2.21) Gradle Build System (v 2.9) Spring Boot (v 1.3) Java (v 1.8) Eclipse IDE This is a part of  Jersey (JAX-RS) Restful Web Services Development Guides series. Please read Jersey + Spring Boot getting started guide . Gradle Build File We are using Gradle for our build and dependency management (Using Maven rather than Gradle is a very trivial task). File: build.gradle buildscript { ext { springBootVersion = '1.3.0.RELEASE' } repositories { mavenCentral() } dependencies { classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}") } } apply plugin: 'java' apply plugin: 'eclipse' a

FastAPI first shot

Setup on my Mac (Macbook Pro 15 inch Retina, Mid 2014) Prerequisite Python 3.6+ (I used 3.7.x. I recently reinstalled OS after cleaning up disk, where stock Python 2.7 was available. I installed Pyenv and then used it to install 3.7.x). I already had a git repo initialized at Github for this project. I checked that out. I use this approach to keep all the source code safe or at a specific place 😀. I set the Python version in .python-version file. I also initialize the virtual environment using pyenv in venv folder. I started the virtual environment. FastAPI specific dependencies setup Now I started with basic pip commands to install dependency for the project. I saved dependencies in requirements.txt  the file. Minimal viable code to spin an API Server FastAPI is as cool as NodeJS or Go Lang (?) to demonstrate the ability to spin an API endpoint up and running in no time. I had the same feeling for the Flask too, which was also super cool. app/main.py: from typing i

Ajax Cross Domain Resource Access Using jQuery

Some time back in our project we faced a problem while making an Ajax call using jQuery. Chrome Browser console had given some weird error message like below when we try to access one of our web pages: When we try to access the same web page in the Firefox browser, it doesn't give any error in the console but some parsing error occurred. In our case, we were accessing XML as an Ajax request resource. I was curious to check if the non-XML cross-domain resource was successfully loading or not. But finally, I realized that it is not going through. jersey-spring-boot-quick-starter-guide In our Ajax call, requesting domain was not the same as the requested URL domain. $.ajax({ url: "https://10.11.2.171:81/xxxxxx/xxxxxxx.xml" , type : "get" , success: function (response) { alert( "Load was performed." ); }, error : function (xhr, status) {