Back to Java
2026-01-025 min read

Function Expressions (Java)

Learn Function Expressions (Java) step by step with clear examples and exercises.

Why This Matters

Function expressions in Java are an essential part of modern programming that allow for greater flexibility and reusability in your code. They enable you to create and use functions as values, making your code more expressive and modular. This guide will delve into the core concept, worked examples, common mistakes, practice questions, and frequently asked questions about Java function expressions.

Why This Matters

Function expressions matter because they help write more concise, reusable, and maintainable code. They allow you to pass functions as arguments to other functions (higher-order functions), making your code modular and easier to test. In addition, function expressions can help you avoid repetition by allowing you to define small functions on the fly, rather than writing separate methods for each individual task.

Prerequisites

To understand Java function expressions, you should be familiar with the following concepts:

  • Basic Java syntax and programming constructs (variables, loops, conditional statements)
  • Method definitions and parameter passing
  • Classes and objects in Java
  • Exception handling
  • Stream API

Core Concept

A function expression is a piece of code that defines a function and can be assigned to a variable or passed as an argument to another function. In Java, you can create function expressions using lambda expressions or method references.

Lambda Expressions

Lambda expressions are anonymous functions that can be used to create function objects at runtime. They consist of three parts:

  1. Parameter list (in parentheses)
  2. Arrow token (->)
  3. Function body (enclosed in curly braces {})

Here's an example of a simple lambda expression that calculates the square of a number:

(int num) -> { return num * num; }

In this example, num is the parameter, and the function body returns the square of the input number. To use this lambda expression, you can assign it to a variable or pass it as an argument to another function:

int square = (int num) -> { return num * num; };
System.out.println(square.apply(4)); // Output: 16

Method References

Method references allow you to refer to an existing method in a class as if it were a lambda expression. This can make your code more readable and easier to understand, especially when working with pre-existing classes.

Here's an example of using a method reference to create a function that sorts an array:

int[] arr = {5, 3, 1, 4};
Arrays.sort(arr, Comparator.naturalOrder()); // Uses the natural ordering of integers
System.out.println(Arrays.toString(arr)); // Output: [1, 3, 4, 5]

In this example, Comparator.naturalOrder() is a method reference that refers to the compare() method in the Comparator interface. By using the method reference, we can sort the array without having to define our own comparison function.

Worked Example

Let's create a simple Java program that calculates the sum of an array using both lambda expressions and method references:

import java.util.Arrays;

int[] arr = {1, 2, 3, 4};

// Using a lambda expression to calculate the sum
int sumLambda = (int num) -> { int total = 0; for (int i = 0; i < arr.length; i++) { total += arr[i]; } return total; };
System.out.println("Sum using lambda: " + sumLambda.apply(arr)); // Output: Sum using lambda: 10

// Using a method reference to calculate the sum (using the Arrays.stream() method)
int sumMethodRef = Arrays.stream(arr).sum();
System.out.println("Sum using method reference: " + sumMethodRef); // Output: Sum using method reference: 10

In this example, we first create an array arr. We then define a lambda expression that calculates the sum of the elements in the array and assign it to the variable sumLambda. Finally, we use a method reference (Arrays.stream(arr).sum()) to calculate the sum using Java's stream API.

Common Mistakes

  1. Forgetting to return a value from the lambda expression or method reference.
  2. Using the wrong parameter types in the lambda expression or method reference.
  3. Not properly closing the parentheses for the lambda expression parameters.
  4. Mixing up the order of the lambda expression parts (parameter list, arrow token, function body).
  5. Forgetting to import necessary classes when using method references.
  6. Incorrectly handling exceptions within a lambda expression.
  7. Overcomplicating lambda expressions by including unnecessary statements or not taking advantage of Java's stream API for simple calculations.

Practice Questions

  1. Write a lambda expression that takes two integers as arguments and returns their sum.
  2. Write a lambda expression that takes an array of integers as an argument and returns the average of the elements in the array.
  3. Use a method reference to sort an array of strings using the compareTo() method in the String class.
  4. Given the following lambda expression: (int num) -> { return num * 2; }, what will be the result of the following code snippet: int result = (int i) -> { return i + ((int j) -> { return j * 2; })(); }(5);

FAQ

Q: What is the difference between a lambda expression and an anonymous class?

A: A lambda expression is a more concise way to create function objects, while an anonymous class requires writing out the entire class definition. Lambda expressions are syntactically simpler and can be used in places where anonymous classes cannot (such as method arguments).

Q: Can I use lambda expressions with primitive types?

A: Yes, you can use lambda expressions with primitive types like int, double, and boolean. However, when using a lambda expression with a primitive type as the return type, the lambda expression must be assigned to a variable of the corresponding wrapper class (e.g., Integer, Double, or Boolean).

Q: How do I handle exceptions in a lambda expression?

A: You can use try-catch blocks within the function body of a lambda expression, just like you would with any other method. However, keep in mind that any exceptions thrown within the lambda expression will be propagated to the calling code.

Q: Can I create a lambda expression with multiple statements?

A: Yes, you can use curly braces {} and semicolons ; to enclose multiple statements within a lambda expression. However, this can make your code less readable, so it's generally best to keep the function body as concise as possible.

Q: How do I handle exceptions when using method references?

A: When using method references, you should consider the exception handling behavior of the original method being referenced. If necessary, you can wrap the method reference in a try-catch block or use a functional interface that includes an exception-handling method (such as java.util.function.BiFunction).

Q: How do I create a lambda expression with multiple parameters?

A: You can define multiple parameters for a lambda expression by listing them separated by commas within the parentheses:

(int num1, int num2) -> { return num1 + num2; }

Q: How do I create a lambda expression that takes an arbitrary number of arguments?

A: You can use Java's varargs feature to define a lambda expression with an arbitrary number of arguments:

(int... numbers) -> { int total = 0; for (int num : numbers) { total += num; } return total; }
Function Expressions (Java) | Java | XQA Learn