Functional Programming in Java

Welcome to our exploration of functional programming in Java! If you’re coming from JavaScript, you’re already familiar with functional concepts. In this lesson, we’ll see how Java implements these ideas and how they compare to what you know in JavaScript.

Lambda Expressions

Java 8 introduced lambda expressions, which are similar to arrow functions in JavaScript. They provide a concise way to represent anonymous functions.

// Java
(parameters) -> expression
// JavaScript
(parameters) => expression;

This is an example of using lambda expressions in Java:

// Java
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
numbers.forEach(n -> System.out.println(n));
// JavaScript
const numbers = [1, 2, 3, 4, 5];
numbers.forEach((n) => console.log(n));

Functional Interfaces

In Java, lambda expressions are tied to the concept of functional interfaces. These are interfaces with a single abstract method.

// Java
@FunctionalInterface
interface Greeting {
    void greet(String name);
}

Greeting javaGreeting = name -> System.out.println("Hello, " + name);
javaGreeting.greet("Alice"); // Outputs: Hello, Alice

In JavaScript, you don’t need a specific interface:

// JavaScript
const jsGreeting = (name) => console.log(`Hello, ${name}`);
jsGreeting('Alice'); // Outputs: Hello, Alice

Stream API

We already saw Java’s Stream API. It allows for elegant functional-style operations on collections.

// Java
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
List<String> filteredNames = names.stream()
                                  .filter(name -> name.startsWith("A"))
                                  .collect(Collectors.toList());
// JavaScript
const names = ['Alice', 'Bob', 'Charlie'];
const filteredNames = names.filter((name) => name.startsWith('A'));

Method References

Method references in Java are shorthand notations for lambda expressions, similar to passing function references in JavaScript.

// Java
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
names.forEach(System.out::println);
// JavaScript
const names = ['Alice', 'Bob', 'Charlie'];
names.forEach(console.log);

Conclusion

Functional programming in Java brings many concepts familiar to JavaScript developers into the Java ecosystem. While the syntax and implementation details differ, the underlying principles remain similar. This approach allows for more concise and expressive code, especially when working with collections and data transformations.

In our next lesson, we’ll dive into concurrency and multithreading in Java, exploring how Java handles parallel execution compared to JavaScript’s event loop and asynchronous programming model. Get ready to unlock the power of multi-core processing in your Java applications!