Functional Programming

Functional programming is a programming paradigm that emphasizes the use of functions that don't have side effects and always return the same output for a given input. This makes code more concise, predictable, and easier to test.

Here are some of the key concepts of functional programming:

* Pure functions: A pure function is a function that doesn't have side effects and always returns the same output for a given input.
* Immutability: Immutability is the state of being unable to change. In functional programming, data is typically immutable, meaning that it cannot be changed once it is created.
* Higher-order functions: A higher-order function is a function that can take other functions as arguments or return other functions as results.
* Function composition: Function composition is the process of combining multiple functions into a single function.
* Currying:Currying is the process of transforming a function that takes multiple arguments into a sequence of functions that each take a single argument.

Functional programming has a number of benefits, including:

* Conciseness: Functional code is often more concise than imperative code. This is because functional code avoids side effects and uses pure functions.
* Predictability: Functional code is more predictable than imperative code. This is because functional code does not modify state, which can lead to unexpected behavior.
* Testability: Functional code is easier to test than imperative code. This is because functional code is isolated and does not rely on external state.

Java has a number of features that support functional programming, including:

* Lambda expressions: Lambda expressions allow you to create anonymous functions.
* Streams: Streams provide a way to process data in a functional way.
* Higher-order functions: Java provides a number of higher-order functions, such as `filter()`, `map()`, and `reduce()`.
* Function composition: Java supports function composition through the use of method chaining.
* Currying: Java supports currying through the use of partial functions.

Here are some examples of how to use functional programming in Java:

Java

```
<// Pure function
public static int add(int a, int b) {
    return a + b;
}

// Immutability
publicclassPoint{
    privatefinalint x;
    privatefinalint y;

    publicPoint(int x, int y){
        this.x = x;
        this.y = y;
    }

    publicintgetX(){
        return x;
    }

    publicintgetY(){
        return y;
    }
}

// Higher-order function
public static List<String> filter(List<String> strings, Predicate<String> predicate) {
    List<String> filteredStrings = new ArrayList<>();
    for (String string : strings) {
        if (predicate.test(string)) {
            filteredStrings.add(string);
        }
    }
    return filteredStrings;
}

// Function composition
public static List<Integer> mapAndReduce(List<String> strings, Function<String, Integer> mapper, BinaryOperator<Integer> reducer) {
    List<Integer> integers = new ArrayList<>();
    for (String string : strings) {
        integers.add(mapper.apply(string));
    }
    return integers.stream().reduce(reducer).collect(Collectors.toList());
}

// Currying
public static Function<Integer, Function<Integer, Integer>> adder() {
    return (a) -> (b) -> a + b;
}

```

Here are some more methods of functional programming in Java and their examples:

This example uses the `map()` method to convert a list of strings to all upper case. The `map()` method takes a function as input and applies it to each element of the list. The function in this example converts a string to upper case.

filter() | `List<Integer> evenNumbers = Arrays.asList(1, 2, 3, 4, 5).stream().filter(n -> n % 2 == 0).collect(Collectors.toList());` This example uses the `filter()` method to filter a list of numbers to only include even numbers. The `filter()` method takes a predicate as input and returns a new list containing only the elements of the original list that satisfy the predicate. The predicate in this example returns `true` if the number is even and `false` otherwise.

reduce() | `Integer sum = Arrays.asList(1, 2, 3, 4, 5).stream().reduce(0, (a, b) -> a + b).intValue();` This example uses the `reduce()` method to reduce a list of numbers to a single value, which is the sum of all the numbers in the list. The `reduce()` method takes a binary operator as input and combines the elements of the list using the binary operator. The binary operator in this example adds two numbers together.

flatMap() | `List<String> allCharacters = Arrays.asList("Alice", "Bob", "Carol").stream().flatMap(s -> s.chars().mapToObj(c -> (char) c)).collect(Collectors.toList());` This example uses the `flatMap()` method to flatten a list of strings into a single list of characters. The `flatMap()` method takes a function as input and applies it to each element of the list, returning a new stream. The function in this example converts a string to a stream of characters.

sorted() | `List<Integer> sortedNumbers = Arrays.asList(5, 3, 2, 1, 4).stream().sorted().collect(Collectors.toList());` This example uses the `sorted()` method to sort a list of numbers in ascending order. The `sorted()` method returns a new stream containing the elements of the original list sorted in ascending order.

These are just a few examples of methods that can be used for functional programming in Java. For more information, I recommend reading the following resources:

* Functional Programming in Java: https://www.geeksforgeeks.org/functional-programming-in-java-with-examples/
* Thinking in Java: https://www.amazon.com/Thinking-Java-4th-Bruce-Eckel/dp/0131872486
* Scala: https://www.scala-lang.org/

Functional programming can be a powerful tool for writing more concise, predictable, and testable code. By learning the basics of functional programming, you can improve your Java programming skills and write better code.

**Sources**

1. https://medium.com/@samuelsinger/triple-add-function-91de11c58601

2. https://www.happycoders.eu/java/records/