# Functional Programming Basics
Functional programming (FP) is a programming paradigm that treats computation as the evaluation of mathematical functions and avoids changing state and mutable data. It focuses on writing code that is declarative, where you express *what* to do rather than *how* to do it. Java, which is primarily an object-oriented language, introduced several features (like Lambda expressions, Streams, etc.) in Java 8 to support functional programming principles.
Letâs dive deeper into the basics of functional programming, its core concepts, and how Java supports them.
---
### 1\. **Immutability**
Immutability is one of the core concepts of functional programming. An immutable object is one whose state cannot be changed after it is created. In FP, rather than modifying the state of objects, new instances are returned after performing transformations. This leads to fewer side effects, making the code easier to reason about and test.
#### Example in Java:
```java
// Example of an immutable object
public class Person {
private final String name;
private final int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
}
```
In this example, the `Person` object is immutable because its fields are `final` and can only be set via the constructor. Once a `Person` object is created, its state cannot be changed.
---
### 2\. **First-Class Functions**
In functional programming, functions are first-class citizens. This means that functions can be passed as arguments to other functions, returned as values from functions, and assigned to variables.
#### Example in Java:
Java supports this concept using Lambda expressions and functional interfaces.
```java
// Function that takes another function as an argument
public class Main {
public static void main(String[] args) {
System.out.println(applyFunction(x -> x * 2, 5)); // Output: 10
}
// Function that accepts a function as an argument
public static int applyFunction(IntFunction func, int value) {
return func.apply(value);
}
}
@FunctionalInterface
interface IntFunction {
int apply(int value);
}
```
In this example, we define a functional interface `IntFunction`, which represents a function that takes an `int` and returns an `int`. We then pass a lambda expression `(x -> x * 2)` to the `applyFunction` method.
---
### 3\. **Pure Functions**
A pure function is a function that has the following characteristics:
* It always produces the same output for the same input.
* It has no side effects (i.e., it does not modify any external state or variables).
Pure functions are central to functional programming because they allow for easier testing, debugging, and parallel execution, as there are no hidden states or side effects to consider.
#### Example in Java:
```java
public class Main {
public static void main(String[] args) {
System.out.println(add(2, 3)); // Output: 5
}
// Pure function
public static int add(int a, int b) {
return a + b;
}
}
```
The `add()` function is a pure function because it always returns the same result when given the same inputs, and it does not modify any external state.
---
### 4\. **Higher-Order Functions**
A higher-order function is a function that either:
* Takes one or more functions as arguments, or
* Returns a function as a result.
In Java, higher-order functions can be easily implemented using Lambda expressions and functional interfaces.
#### Example in Java:
```java
// Higher-order function example
public class Main {
public static void main(String[] args) {
// Using a higher-order function to generate a multiplier
Function