Functional Programming in Java
- 2021-11-29 07:10:56
- OfStack
3.3 Function3.4 Supplier3.5 Primitive Specializations
4. Type Check4.1 Capturing Lambda5, Method Reference 5.1 Constructor Reference 5.2 Combination Lambda5.3 Comparators5.4 Predicates5.5 Functions6, Summary
Functional programming is a programming paradigm in which programs are constructed by applying and combining functions. It is a declarative programming paradigm, in which function definitions are expression trees, and each expression tree returns 1 value instead of a series of command statements that change the state of the program
Java8
Introduced
Lambda
Functional programming in the form. Terminology
Lambda
From
Lambda
Calculus, used to describe calculation.
1. Lambda
We can put
lambda
An expression is treated as an anonymous function that can be assigned to a variable and passed to a method that accepts the function interface as an argument. The Lambda expression has no name, but it has a parameter list, a body, and a return type.
(parameters) -> expression
lambda
Expressions can be used in the context of function interfaces.
2. Function interface
A function interface is an interface that specifies only one abstract method.
public interface Comparator<T> {
int compare(T o1, T o2);
}
public interface Runnable {
void run();
}
Lambda
Expressions allow us to directly inline the implementation of an abstract method that provides a function interface and treat the entire expression as an instance of the function interface.
2.1 Function descriptors
We call the signature of the abstract method of the function interface a function descriptor. Function descriptor description
lambda
The signature of the expression. For example, we can put
Runnable
The function descriptor of is regarded as
Lambda
0
Because it has an abstract method that accepts nothing and returns nothing (
Lambda
1
).
3. Java function interface
3.1 Predicate
Lambda
2
Interface defines a file named
Lambda
3
That accepts a generic type of
Lambda
4
And returns 1 Boolean value. This interface can be used to represent Boolean expressions that use T type objects.
Function descriptor:
Lambda
5
@FunctionalInterface
public interface Predicate<T> {
boolean test(T t);
}
3.2 Consumer
Lambda
6
Interface defines a file named
Lambda
7
That accepts an object of generic type T and returns no results (void). We can use this interface when we need to access and perform some operations on objects of type T.
Function descriptor:
Lambda
8
3.3 Function
Lambda
9
Interface defines a file named
Lambda
0
That takes an object of generic type T as input and returns an object of generic type R. When we need to define a
lambda
You can use this interface when mapping information from input objects to output.
Function descriptor:
Lambda
2
3.4 Supplier
Interface
Lambda
3
Defines a file named
Lambda
4
That accepts nothing and returns an object of type T.
Function descriptor:
Lambda
5
3.5 Primitive Specializations
A primitive interface is a dedicated interface used to avoid automatic boxing when the input or output is a primitive.
public interface IntPredicate {
boolean test(int t);
}
4. Type check
lambda
The type of is derived from using the
lambda
Deduced from the context of. In context
lambda
The type required by an expression (for example, a method parameter passed to it or a local variable assigned to it) is called the target type.
Lambda
An expression can get its target type from an assignment context, a method invocation context (parameters and returns), and a cast context.
Object o = (Runnable) () -> System.out.println("Hello");
4.1 Capturing Lambda
lambda
Instance variables and static variables can be captured (referenced in their bodies) without restriction. But when local variables are captured, they must be explicitly declared as final or actually
Lambda
1
.
Why do we have this restriction?
Instance variables are stored on the heap, while local variables are on the stack. If
lambda
You can access local variables directly, and
lambda
Use in a thread, then use the
lambda
You can try to access a variable after the thread that allocated it has unallocated it. Therefore,
Java
Implement access to a free local variable as access to its copy, not to the original variable. If the local variable is assigned only once, it makes no difference, so there are restrictions.
5. Method references
There are three main method references:
A method reference to a static method. For example, – Integer::parseInt
A method reference to an instance method of any type. Example
– String::length
A method reference to an instance method of an existing object or expression. Example
– student::getRank
, of which
student
Is a method
getRank()
Adj.
student
Local variables of type
List<String> list = Arrays.asList("a","b","A","B");
list.sort((s1, s2) -> s1.compareToIgnoreCase(s2));
It can be written as
List<String> list = Arrays.asList("a","b","A","B");
list.sort(String::compareToIgnoreCase);
5.1 Constructor Reference
You can use the
ClassName::new
Reference to an existing constructor
Supplier<List<String>> supplier = ArrayList::new ; And Supplier<List<String>> supplier = () -> new ArrayList<>() Same;
5.2 Combination Lambda
Many functional interfaces contain functions that can be used to combine
lambda
The default method of the expression. Combination sample-
Combine two predicates into a larger predicate and perform or operation between the two predicates
Reverse or chain comparator
5.3 Comparators
Arrange students in reverse order
Comparator<Student> c = Comparator.comparing(Student::getRank);
students.sort(comparing(Student::getRank).reversed());
Sort students by name (reverse), and then arrange them in reverse order
students.sort(comparing(Student::getName).reversed()
.thenComparing(Student::getRank));
5.4 Predicates
The Predicates interface includes three methods:
negate
,
and
, and
or
Which can be used to create more complex predicates.
Predicate<Integer> naturalNumber = i -> i > 0;
Predicate<Integer> naturalNumberLessThanHundred = naturalNumber.and( i -> i < 100);
5.5 Functions
The function interface has two default methods,
andThen
And
compose
.
Consider f(x) = x2 and g(x) = x3 + 1 then
(parameters) -> expression
0
@FunctionalInterface
public interface Predicate<T> {
boolean test(T t);
}
0
(parameters) -> expression
1
@FunctionalInterface
public interface Predicate<T> {
boolean test(T t);
}
1
Applying Lambda
Let's see how to write a general method based on
(parameters) -> expression
2
Property filters 1 group of books as
(parameters) -> expression
3
Adj.
(parameters) -> expression
4
Clause).
@FunctionalInterface
public interface Predicate<T> {
boolean test(T t);
}
2
Lambda
Expression filters different books through different filters
List<Book> javaBook = filter(book -> book.getCategory().equals(JAVA));
List<Book> joshuaBlochBook = filter(book -> book.getAuthor().equals("Joshua Bloch"));
6. Summary
lambda
An expression can be considered an anonymous function and can be used in the context of a function interface. A function interface is an interface that specifies only one abstract method.