Java 8 – Primitive Function Functional Interface

In this article, we will discuss different variation of pre-defined Function Functional Interface available for primitive data-types like int, long, double, etc. in Java 1.8 version

1. Primitive Function Functional Interface (input argument) :

  • This is very similar to Function Functional Interface but it always accepts 1 input argument of type primitive-type like int, long and double, whereas Function allows to accepts any data-type and return result in any data-type
  • Performance-wise primitive Function is much faster compared to Function<T, R>
  • There are lot of conversion happening for auto-boxing & auto-unboxing for converting primitive-type to wrapper-type and again wrapper-type to primitive-type and so on
  • To avoid unnecessary conversion between primitive-type to wrapper-type and vice-versa, primitive-type specific Function Functional Interface for conversion introduced in Java 1.8 version as listed below,
  1. IntFunction
  2. LongFunction
  3. DoubleFunction

We will look into method signature along with example for each one of the above primitive Function Functional Interface

1.1 IntFunction Functional Interface

  • This primitive IntFunction Functional Interface accepts 1-input argument of primitive int type and it is not required to declare while defining IntFunction (or lambda expression)
  • But we have to provide return-type for IntFunction<R> and it can be any data-type depending upon our requirement
  • Method signature: R apply(int value);
package java.util.function;

import java.util.function.Function;

@FunctionalInterface
public interface IntFunction<R> {

    /**
     * Applies this function to the given argument.
     *
     * @param value the function argument
     * @return the function result
     */
    R apply(int value);
}

Example for IntFunction :

  • Here, while defining lambda expression using IntFunction we haven’t specified any data-type like Integer for input argument, still compiler doesn’t complain and executed well
  • And we have provided return-type as Integer, as square of number will be Integer only
  • Caution: but if we pass any other data-type like String or double then compile-time error will be thrown stating “The method apply(int) in the type IntFunction is not applicable for the arguments (double)
package net.bench.resources.primitive.function.example;

import java.util.function.IntFunction;

public class IntFunctionExample {

	public static void main(String[] args) {

		// lambda expression to find square of number using IntFunction FI
		IntFunction<Integer> f = i -> i*i;

		// computing Square of an Integer using IntFunction FI
		System.out.println("1. The Square of number 5 is \t: " 
				+ f.apply(5));

		System.out.println("2. The Square of number 9 is \t: " 
				+ f.apply(9));

		System.out.println("3. The Square of number 27 is \t: " 
				+ f.apply(27));

		System.out.println("4. The Square of number 33 is \t: " 
				+ f.apply(33));

		System.out.println("5. The Square of number 43 is \t: " 
				+ f.apply(43));
	}
}

Output:

1. The Square of number 5 is 	: 25
2. The Square of number 9 is 	: 81
3. The Square of number 27 is 	: 729
4. The Square of number 33 is 	: 1089
5. The Square of number 43 is 	: 1849

1.2 LongFunction Functional Interface

  • This primitive LongFunction accepts 1-input argument of primitive long type and it is not required to declare while defining LongFunction (or lambda expression)
  • But we have to provide return-type for LongFunction<R> and it can be any data-type depending upon our requirement
  • Method signature: R apply(long value);
package java.util.function;

import java.util.function.Function;

@FunctionalInterface
public interface LongFunction<R> {

    /**
     * Applies this function to the given argument.
     *
     * @param value the function argument
     * @return the function result
     */
    R apply(long value);
}

Example for LongFunction :

  • Here, while defining lambda expression using LongFunction we haven’t specified any data-type like Long for input argument, still compiler doesn’t complain and executed well
  • And we have provided return-type as Boolean, as lambda expression evaluates whether provided long value is positive or negative
  • Caution: but if we pass any other data-type like String or double then compile-time error will be thrown stating “The method apply(long) in the type LongFunction is not applicable for the arguments (double)
package net.bench.resources.primitive.function.example;

import java.util.function.LongFunction;

public class LongFunctionExample {

	public static void main(String[] args) {

		// lambda expression for LongFunction to check number is positive or negative
		LongFunction<Boolean> lf = longNum ->  longNum >= 0;

		// testing for different numbers using above lambda expression
		System.out.println("1. Whether 10 is postive number : "
				+ lf.apply(10));

		System.out.println("2. Whether -7 is postive number : "
				+ lf.apply(-7));

		System.out.println("3. Whether 19 is postive number : "
				+ lf.apply(19));

		System.out.println("4. Whether -32 is postive number : "
				+ lf.apply(-32));

		System.out.println("5. Whether 41 is postive number : "
				+ lf.apply(41));
	}
}

Output:

1. Whether 10 is postive number : true
2. Whether -7 is postive number : false
3. Whether 19 is postive number : true
4. Whether -32 is postive number : false
5. Whether 41 is postive number : true

1.3 DoubleFunction Functional Interface

  • This primitive DoubleFunction accepts 1-input argument of primitive double type and it is not required to declare while defining DoubleFunction (or lambda expression)
  • But we have to provide return-type for DoubleFunction<R> and it can be any data-type depending upon our requirement
  • Method signature: R apply(double value);
package java.util.function;

import java.util.function.Function;

@FunctionalInterface
public interface DoubleFunction<R> {

    /**
     * Applies this function to the given argument.
     *
     * @param value the function argument
     * @return the function result
     */
    R apply(double value);
}

Example for DoubleFunction :

  • Here, while defining lambda expression using DoubleFunction we haven’t specified any data-type like Double for input argument, still compiler doesn’t complain and executed well
  • And we have provided return-type as String, as lambda expression return String value
  • Caution: but if we pass any other data-type like String then compile-time error will be thrown stating “The method apply(double) in the type DoubleFunction is not applicable for the arguments (String)
package net.bench.resources.primitive.function.example;

import java.util.function.DoubleFunction;

public class DoubleFunctionExample {

	public static void main(String[] args) {

		// lambda expression for DoubleFunction to check CGPA is greater than 6.7
		DoubleFunction<String> df = d -> "you have cleared IIT-JEE with " + d + " CGPA";

		// testing for different numbers using above lambda expression
		System.out.println("Suresh, " + df.apply(9.2));

		System.out.println("Naresh, " + df.apply(6.7));

		System.out.println("Rajesh, " + df.apply(7.9));

		System.out.println("Ramesh, " + df.apply(8.9));

		System.out.println("Lokesh, " + df.apply(7.3));
	}
}

Output:

Suresh, you have cleared IIT-JEE with 9.2 CGPA
Naresh, you have cleared IIT-JEE with 6.7 CGPA
Rajesh, you have cleared IIT-JEE with 7.9 CGPA
Ramesh, you have cleared IIT-JEE with 8.9 CGPA
Lokesh, you have cleared IIT-JEE with 7.3 CGPA

2. Primitive Function Functional Interface (return-type) :

  • This is very similar to Function Functional Interface where it accepts 1 input argument of any data-type but return-type must be primitive-type like int, long and double, etc, whereas Function allows to accepts any data-type and return result in any data-type
  • Performance-wise primitive Function is much faster compared to Function<T, R>
  • There are lot of conversion happening for auto-boxing & auto-unboxing for converting primitive-type to wrapper-type and again wrapper-type to primitive-type and so on
  • To avoid unnecessary conversion between primitive-type to wrapper-type and vice-versa, primitive-type specific Function Functional Interface for conversion introduced in Java 1.8 version as listed below,
  1. ToIntFunction
  2. ToLongFunction
  3. ToDoubleFunction

We will look into method signature along with example for each one of the above primitive Function Functional Interface

2.1 ToIntFunction Functional Interface

  • This primitive ToIntFunction Functional Interface always returns value in primitive-type int only and it is not required to declare while defining ToIntFunction (or lambda expression)
  • But we have to provide input argument for ToIntFunction<T> and it can be any data-type depending upon our requirement
  • Method signature: int applyAsInt(T value);
package java.util.function;

import java.util.function.Function;

@FunctionalInterface
public interface ToIntFunction<T> {

    /**
     * Applies this function to the given argument.
     *
     * @param value the function argument
     * @return the function result
     */
    int applyAsInt(T value);
}

Example for ToIntFunction :

  • Here, while defining lambda expression using ToIntFunction we haven’t specified any return-type like Integer, still compiler doesn’t complain and executed well
  • And we have provided input argument type as Integer, as we are calculating square of number
package net.bench.resources.primitive.function.example;

import java.util.function.ToIntFunction;

public class ToIntFunctionExample {

	public static void main(String[] args) {

		// lambda expression to find square of number using ToIntFunction FI
		ToIntFunction<Integer> f = i -> i*i;

		// computing Square of an Integer using Function FI
		System.out.println("1. The Square of number 5 is \t: " 
				+ f.applyAsInt(5));

		System.out.println("2. The Square of number 9 is \t: " 
				+ f.applyAsInt(9));

		System.out.println("3. The Square of number 27 is \t: " 
				+ f.applyAsInt(27));

		System.out.println("4. The Square of number 33 is \t: " 
				+ f.applyAsInt(33));

		System.out.println("5. The Square of number 43 is \t: " 
				+ f.applyAsInt(43));
	}
}

Output:

1. The Square of number 5 is 	: 25
2. The Square of number 9 is 	: 81
3. The Square of number 27 is 	: 729
4. The Square of number 33 is 	: 1089
5. The Square of number 43 is 	: 1849

2.2 ToLongFunction Functional Interface

  • This primitive ToLongFunction Functional Interface always returns value in primitive-type long only and it is not required to declare while defining ToLongFunction (or lambda expression)
  • But we have to provide input argument for ToLongFunction<T> and it can be any data-type depending upon our requirement
  • Method signature: long applyAsLong(T value);
package java.util.function;

import java.util.function.Function;

@FunctionalInterface
public interface ToLongFunction<T> {

    /**
     * Applies this function to the given argument.
     *
     * @param value the function argument
     * @return the function result
     */
    long applyAsLong(T value);
}

Example for ToLongFunction :

  • Here, while defining lambda expression using ToLongFunction we haven’t specified any return-type like Long, still compiler doesn’t complain and executed well
  • And we have provided input argument type as Integer, as we are multiplying this number with 1024
package net.bench.resources.primitive.function.example;

import java.util.function.ToLongFunction;

public class ToLongFunctionExample {

	public static void main(String[] args) {

		// lambda expression to multiply number with 1024 using ToLongFunction FI
		ToLongFunction<Integer> f = i -> i*1024;

		// multiply below number using above ToLongFunction FI
		System.out.println("1. 5 * 1024 = \t" + f.applyAsLong(5));

		System.out.println("2. 9 * 1024 = \t" + f.applyAsLong(9));

		System.out.println("3. 27 * 1024 = \t" + f.applyAsLong(27));

		System.out.println("4. 33 * 1024 = \t" + f.applyAsLong(33));

		System.out.println("5. 43 * 1024 = \t" + f.applyAsLong(43));
	}
}

Output:

1. 5 * 1024 = 	5120
2. 9 * 1024 = 	9216
3. 27 * 1024 = 	27648
4. 33 * 1024 = 	33792
5. 43 * 1024 = 	44032

2.3 ToDoubleFunction Functional Interface

  • This primitive ToDoubleFunction Functional Interface always returns value in primitive-type double only and it is not required to declare while defining ToDoubleFunction (or lambda expression)
  • But we have to provide input argument for ToDoubleFunction<T> and it can be any data-type depending upon our requirement
  • Method signature: double applyAsDouble(T value);
package java.util.function;

import java.util.function.Function;

@FunctionalInterface
public interface ToDoubleFunction<T> {

    /**
     * Applies this function to the given argument.
     *
     * @param value the function argument
     * @return the function result
     */
    double applyAsDouble(T value);
}

Example for ToDoubleFunction :

  • Here, while defining lambda expression using ToDoubleFunction we haven’t specified any return-type like Double, still compiler doesn’t complain and executed well
  • And we have provided input argument type as Integer, as we are subtracting this number with 0.5 which results in double value to be returned
package net.bench.resources.primitive.function.example;

import java.util.function.ToDoubleFunction;

public class ToDoubleFunctionExample {

	public static void main(String[] args) {

		// lambda expression for ToDoubleFunction FI for subtraction to get double value
		ToDoubleFunction<Integer> df = i -> i - 0.5;

		// testing for different numbers using above lambda expression
		System.out.println("1. After discount, for 5 is \t= "
				+ df.applyAsDouble(5));

		System.out.println("2. After discount, for 7 is \t= "
				+ df.applyAsDouble(7));

		System.out.println("3. After discount, for 32 is \t= "
				+ df.applyAsDouble(32));

		System.out.println("4. After discount, for 28 is \t= "
				+ df.applyAsDouble(28));

		System.out.println("5. After discount, for 25 is \t= "
				+ df.applyAsDouble(55));
	}
}

Output:

1. After discount, for 5 is 	= 4.5
2. After discount, for 7 is 	= 6.5
3. After discount, for 32 is 	= 31.5
4. After discount, for 28 is 	= 27.5
5. After discount, for 25 is 	= 54.5

3. Primitive Function Functional Interface (conversion) :

  • This is very similar to Function Functional Interface but here both input argument type as well as return-type is defined as primitive-types like int, long and double, etc, whereas Function allows to accepts any data-type and return result in any data-type
  • Performance-wise primitive Function is much faster compared to Function<T, R>
  • There are lot of conversion happening for auto-boxing & auto-unboxing for converting primitive-type to wrapper-type and again wrapper-type to primitive-type and so on
  • To avoid unnecessary conversion between primitive-type to wrapper-type and vice-versa, primitive-type specific Function Functional Interface for conversion introduced in Java 1.8 version as listed below,
  1. IntToLongFunction
  2. IntToDoubleFunction
  3. LongToIntFunction
  4. LongToDoubleFunction
  5. DoubleToIntFunction
  6. DoubleToLongFunction

We will look into method signature along with example for each one of the above primitive Function FI

3.1 IntToLongFunction Functional Interface

  • This primitive IntToLongFunction Functional Interface accepts 1-input argument of primitivetype int and returns value in primitive-type long only and it is not required to declare while defining IntToLongFunction (or lambda expression)
  • Method signature: long applyAsLong(int value);
package java.util.function;

import java.util.function.Function;

@FunctionalInterface
public interface IntToLongFunction {

    /**
     * Applies this function to the given argument.
     *
     * @param value the function argument
     * @return the function result
     */
    long applyAsLong(int value);
}

Example for IntToLongFunction :

  • Here, while defining lambda expression using IntToLongFunction we are not defining type for both input argument and return-type
  • As this are fixed now, input argument type should be primitive-type int only and return-type should be primitive-type long only
  • Caution: any other type results in compile-time error
package net.bench.resources.primitive.function.example;

import java.util.function.IntToLongFunction;

public class IntToLongFunctionExample {

	public static void main(String[] args) {

		// lambda expression for IntToLongFunction FI
		IntToLongFunction ilf = i -> i * 2048;

		// testing with different int number
		// multiply below number using above ToLongFunction FI

		System.out.println("1. 5 * 2048 = \t" + ilf.applyAsLong(5));

		System.out.println("2. 9 * 2048 = \t" + ilf.applyAsLong(9));

		System.out.println("3. 27 * 2048 = \t" + ilf.applyAsLong(27));

		System.out.println("4. 33 * 2048 = \t" + ilf.applyAsLong(33));

		System.out.println("5. 43 * 2048 = \t" + ilf.applyAsLong(43));
	}
}

Output:

1. 5 * 2048 = 	10240
2. 9 * 2048 = 	18432
3. 27 * 2048 = 	55296
4. 33 * 2048 = 	67584
5. 43 * 2048 = 	88064

3.2 IntToDoubleFunction Functional Interface

  • This primitive IntToDoubleFunction Functional Interface accepts 1-input argument of primitive-type int and returns value in primitive-type double only and it is not required to declare while defining IntToDoubleFunction (or lambda expression)
  • Method signature: double applyAsDouble(int value);
package java.util.function;

import java.util.function.Function;

@FunctionalInterface
public interface IntToDoubleFunction {

    /**
     * Applies this function to the given argument.
     *
     * @param value the function argument
     * @return the function result
     */
    double applyAsDouble(int value);
}

Example for IntToDoubleFunction :

  • Here, while defining lambda expression using IntToDoubleFunction we are not defining type for both input argument and return-type
  • As this are fixed now, input argument type should be primitive-type int only and return-type should be primitive-type double only
  • Caution: any other type results in compile-time error
package net.bench.resources.primitive.function.example;

import java.util.function.IntToDoubleFunction;

public class IntToDoubleFunctionExample {

	public static void main(String[] args) {

		// lambda expression for IntToDoubleFunction FI
		IntToDoubleFunction idf = i -> i * 0.05;

		// testing with different int number
		// multiply below number using above ToDoubleFunction FI

		System.out.println("1. 7 * 0.05 = \t" + idf.applyAsDouble(7));

		System.out.println("2. 19 * 0.05 = \t" + idf.applyAsDouble(19));

		System.out.println("3. 23 * 0.05 = \t" + idf.applyAsDouble(23));

		System.out.println("4. 33 * 0.05 = \t" + idf.applyAsDouble(33));

		System.out.println("5. 41 * 0.05 = \t" + idf.applyAsDouble(41));
	}
}

Output:

1. 7 * 0.05 = 	0.35000000000000003
2. 19 * 0.05 = 	0.9500000000000001
3. 23 * 0.05 = 	1.1500000000000001
4. 33 * 0.05 = 	1.6500000000000001
5. 41 * 0.05 = 	2.0500000000000003

3.3 LongToIntFunction Functional Interface

  • This primitive LongToIntFunction Functional Interface accepts 1-input argument of primitive-type long and returns value in primitive-type int only and it is not required to declare while defining LongToIntFunction (or lambda expression)
  • Method signature: int applyAsInt(long value);
package java.util.function;

import java.util.function.Function;

@FunctionalInterface
public interface LongToIntFunction {

    /**
     * Applies this function to the given argument.
     *
     * @param value the function argument
     * @return the function result
     */
    int applyAsInt(long value);
}

Example for LongToIntFunction :

  • Here, while defining lambda expression using LongToIntFunction we are not defining type for both input argument and return-type
  • As this are fixed now, input argument type should be primitive-type long only and return-type should be primitive-type int only
  • Caution: any other type results in compile-time error
package net.bench.resources.primitive.function.example;

import java.util.function.LongToIntFunction;

public class LongToIntFunctionExample {

	public static void main(String[] args) {

		// lambda expression for IntToLongFunction FI
		LongToIntFunction lif = l -> (int)(l/1024);

		// divide below number by 1024 using above LongToIntFunction FI
		System.out.println("1. 2048 / 1024 = " + lif.applyAsInt(2048));

		System.out.println("2. 7168 / 1024 = " + lif.applyAsInt(7168));

		System.out.println("3. 19456 / 1024 = " + lif.applyAsInt(19456));

		System.out.println("4. 31744 / 1024 = " + lif.applyAsInt(31744));

		System.out.println("5. 65536 / 1024 = " + lif.applyAsInt(65536));
	}
}

Output:

1. 2048 / 1024 = 2
2. 7168 / 1024 = 7
3. 19456 / 1024 = 19
4. 31744 / 1024 = 31
5. 65536 / 1024 = 64

3.4 LongToDoubleFunction Functional Interface

  • This primitive LongToDoubleFunction Functional Interface accepts 1-input argument of primitive-type long and returns value in primitive-type double only and it is not required to declare while defining LongToDoubleFunction (or lambda expression)
  • Method signature: double applyAsDouble(long value);
package java.util.function;

import java.util.function.Function;

@FunctionalInterface
public interface LongToDoubleFunction {

    /**
     * Applies this function to the given argument.
     *
     * @param value the function argument
     * @return the function result
     */
    double applyAsDouble(long value);
}

Example for LongToDoubleFunction :

  • Here, while defining lambda expression using LongToDoubleFunction we are not defining type for both input argument and return-type
  • As this are fixed now, input argument type should be primitive-type long only and return-type should be primitive-type int only
  • Caution: any other type results in compile-time error
package net.bench.resources.primitive.function.example;

import java.util.function.LongToDoubleFunction;

public class LongToDoubleExample {

	public static void main(String[] args) {

		// lambda expression for LongToDoubleFunction FI
		LongToDoubleFunction ltd = l -> l * 0.123;

		// test with few long values

		System.out.println("1. 123456 * 0.123 = " + ltd.applyAsDouble(123456));

		System.out.println("2. 654321 * 0.123 = " + ltd.applyAsDouble(654321));

		System.out.println("3. 963258 * 0.123 = " + ltd.applyAsDouble(963258));

		System.out.println("4. 741236 * 0.123 = " + ltd.applyAsDouble(741236));

		System.out.println("5. 842657 * 0.123 = " + ltd.applyAsDouble(842657));
	}
}

Output:

1. 123456 * 0.123 = 15185.088
2. 654321 * 0.123 = 80481.483
3. 963258 * 0.123 = 118480.734
4. 741236 * 0.123 = 91172.028
5. 842657 * 0.123 = 103646.811

3.5 DoubleToIntFunction Functional Interface

  • This primitive DoubleToIntFunction Functional Interface accepts 1-input argument of primitive-type double and returns value in primitive-type int only and it is not required to declare while defining DoubleToIntFunction (or lambda expression)
  • Method signature: int applyAsInt(double value);
package java.util.function;

import java.util.function.Function;

@FunctionalInterface
public interface DoubleToIntFunction {

    /**
     * Applies this function to the given argument.
     *
     * @param value the function argument
     * @return the function result
     */
    int applyAsInt(double value);
}

Example for DoubleToIntFunction :

  • Here, while defining lambda expression using DoubleToIntFunction we are not defining type for both input argument and return-type
  • As this are fixed now, input argument type should be primitive-type double only and return-type should be primitive-type int only
  • Caution: any other type results in compile-time error
package net.bench.resources.primitive.function.example;

import java.util.function.DoubleToIntFunction;

public class DoubleToIntFunctionExample {

	public static void main(String[] args) {

		// lambda expression for DoubleToIntFunction FI
		DoubleToIntFunction dti = d -> (int)d;

		// test above lambda with few number

		System.out.println("1. After removing fractional part from 9.3 \t= "
				+ dti.applyAsInt(9.3));

		System.out.println("2. After removing fractional part from 99.623 \t= "
				+ dti.applyAsInt(99.623));

		System.out.println("3. After removing fractional part from 63.124 \t= "
				+ dti.applyAsInt(63.124));

		System.out.println("4. After removing fractional part from -35.25 \t= "
				+ dti.applyAsInt(-35.25));

		System.out.println("5. After removing fractional part from 0.23658 \t= "
				+ dti.applyAsInt(0.23658));
	}
}

Output:

1. After removing fractional part from 9.3 	= 9
2. After removing fractional part from 99.623 	= 99
3. After removing fractional part from 63.124 	= 63
4. After removing fractional part from -35.25 	= -35
5. After removing fractional part from 0.23658 	= 0

3.6 DoubleToLongFunction Functional Interface

  • This primitive DoubleToLongFunction Functional Interface accepts 1-input argument of primitive-type double and returns value in primitive-type long only and it is not required to declare while defining DoubleToLongFunction (or lambda expression)
  • Method signature: long applyAsLong(double value);
package java.util.function;

import java.util.function.Function;

@FunctionalInterface
public interface DoubleToLongFunction {

    /**
     * Applies this function to the given argument.
     *
     * @param value the function argument
     * @return the function result
     */
    long applyAsLong(double value);
}

Example for DoubleToLongFunction :

  • Here, while defining lambda expression using DoubleToLongFunction we are not defining type for both input argument and return-type
  • As this are fixed now, input argument type should be primitive-type double only and return-type should be primitive-type long only
  • Caution: any other type results in compile-time error
package net.bench.resources.primitive.function.example;

import java.util.function.DoubleToLongFunction;

public class DoubleToLongFunctionExample {

	public static void main(String[] args) {

		// lambda expression for DoubleToLongFunction FI
		DoubleToLongFunction dti = d -> (long)d;

		// test above lambda with few number

		System.out.println("1. After removing fractional part from 3.14 \t= "
				+ dti.applyAsLong(3.14));

		System.out.println("2. After removing fractional part from 22.7 \t= "
				+ dti.applyAsLong(22.7));

		System.out.println("3. After removing fractional part from 36.421 \t= "
				+ dti.applyAsLong(36.421));

		System.out.println("4. After removing fractional part from -27.45 \t= "
				+ dti.applyAsLong(-27.45));

		System.out.println("5. After removing fractional part from 0.12345 \t= "
				+ dti.applyAsLong(0.12345));
	}
}

Output:

1. After removing fractional part from 3.14 	= 3
2. After removing fractional part from 22.7 	= 22
3. After removing fractional part from 36.421 	= 36
4. After removing fractional part from -27.45 	= -27
5. After removing fractional part from 0.12345 	= 0

References:

Happy Coding !!
Happy Learning !!

Java 8 - Primitive BiFunction Functional Interface
Java 8 - Primitive Predicate Functional Interface