函数式接口(Function Interface)就是一个有且仅有一个抽象方法,但是可以有多个非抽象方法的接口。函数式接口可以被隐式的转换为Lambda表达式。
定义一个函数式接口如下:
@FunctionalInterface
interface GreetingService {
void sayMessage(String message);
}
JDK1.8 新增加的函数式接口:
java.util.function它包含了很多类,用来支持Java的函数式编程,该包中的函数式接口有:
序号 |
接口 |
Lambda表达式 |
描述 |
1 |
BiConsumer |
(T,U) ->{} |
代表了一个接受两个输入参数的操作,并且不返回任何结果。 |
2 |
BiFunction |
(T,U)->{R} |
代表了一个接受两个输入参数的方法,并且返回一个结果。 |
3 |
BinaryOperator |
(T,T)->{T} |
代表了一个作用于两个同类型操作符的操作,并且返回了操作符同类型的结果。 |
4 |
BiPredicate |
(T,U)->{boolean} |
代表了一个接收两个参数并且返回boolean值方法。 |
5 |
BooleanSupplier |
()->{boolean} |
代表了boolean值结果的提供方。 |
6 |
Consumer |
(T)->{} |
代表了接受一个输入参数并且无返回的操作。 |
7 |
DoubleBinaryOperator |
(double,double)->{double} |
代表了作用于两个double值操作符的操作,并且返回了一个double值的结果。 |
8 |
DoubleConsumer |
(double)->{} |
代表一个接受double值参数的操作,并且不返回结果。 |
9 |
DoubleFunction |
(double)->{R} |
代表接受一个double值参数的方法,并且返回结果。 |
10 |
DoublePredicate |
(double)->{boolean} |
代表一个拥有double值参数的boolean值方法。 |
11 |
DoubleSupplier |
()->{double} |
代表一个double值结构的提供方。 |
12 |
DoubleToIntFunction |
(double)->{int} |
接受一个double类型输入,返回一个int类型结果。 |
13 |
DoubleToLongFunction |
(double)->{long} |
接受一个double类型输入,返回一个long类型结果。 |
14 |
DoubleUnaryOperator |
(double)->{double} |
接受一个参数同为类型double,返回值类型也为double 。 |
15 |
Function |
(T)->{R} |
接受一个输入参数,返回一个结果。 |
16 |
IntBinaryOperator |
(int,int)->{int} |
接受两个参数同为类型int,返回值类型也为int 。 |
17 |
IntConsumer |
(int)->{} |
接受一个int类型的输入参数,无返回值 。 |
18 |
IntFunction |
(int)->{R} |
接受一个int类型输入参数,返回一个结果 。 |
19 |
IntPredicate |
(int)->{boolean} |
接受一个int输入参数,返回一个布尔值的结果。 |
20 |
IntSupplier |
()->{int} |
无参数,返回一个int类型结果。 |
21 |
IntToDoubleFunction |
(int)->{double} |
接受一个int类型输入,返回一个double类型结果 。 |
22 |
IntToLongFunction |
(int)->{long} |
接受一个int类型输入,返回一个long类型结果。 |
23 |
IntUnaryOperator |
(int)->{int} |
接受一个参数同为类型int,返回值类型也为int 。 |
24 |
LongBinaryOperator |
(long,long)->{long} |
接受两个参数同为类型long,返回值类型也为long。 |
25 |
LongConsumer |
(long)->{} |
接受一个long类型的输入参数,无返回值。 |
26 |
LongFunction |
(long)->{R} |
接受一个long类型输入参数,返回一个结果。 |
27 |
LongPredicate |
(long)->{boolean} |
接受一个long输入参数,返回一个布尔值类型结果。 |
28 |
LongSupplier |
()->{long} |
无参数,返回一个结果long类型的值。 |
29 |
LongToDoubleFunction |
(long)->{double} |
接受一个long类型输入,返回一个double类型结果。 |
30 |
LongToIntFunction |
(long)->{int} |
接受一个long类型输入,返回一个int类型结果。 |
31 |
LongUnaryOperator |
(long)->{long} |
接受一个参数同为类型long,返回值类型也为long。 |
32 |
ObjDoubleConsumer |
(Object,double)->{} |
接受一个object类型和一个double类型的输入参数,无返回值。 |
33 |
ObjIntConsumer |
(Object,int)->{} |
接受一个object类型和一个int类型的输入参数,无返回值。 |
34 |
ObjLongConsumer |
(Object,long)->{} |
接受一个object类型和一个long类型的输入参数,无返回值。 |
35 |
Predicate |
(T)->{boolean} |
接受一个输入参数,返回一个布尔值结果。 |
36 |
Supplier |
()->{T} |
无参数,返回一个结果。 |
37 |
ToDoubleBiFunction |
(T,U)->{dobule} |
接受两个输入参数,返回一个double类型结果 |
38 |
ToDoubleFunction |
(T)->{double} |
接受一个输入参数,返回一个double类型结果 |
39 |
ToIntBiFunction |
(T,U)->{int} |
接受两个输入参数,返回一个int类型结果。 |
40 |
ToIntFunction |
(int)->{int} |
接受一个输入参数,返回一个int类型结果。 |
41 |
ToLongBiFunction |
(T,U)->{long} |
接受两个输入参数,返回一个long类型结果。 |
42 |
ToLongFunction |
(T)->{long} |
接受一个输入参数,返回一个long类型结果。 |
43 |
UnaryOperator |
(T)->{T} |
接受一个参数为类型T,返回值类型也为T。 |
Lambda表达式,也可称为闭包,它是推动Java8 发布的最重要的新特征,Lambda允许把函数作为一个方法的参数传递进方法中。使用Lambda表达式可以使代码变的更加简洁紧凑。
Lambda表达式的语法格式如下:
(parameters) -> expression
或
(parameters) ->{ statements; }
以下是Lambda表达式的重要特征:
Lambda表达式的简单例子:
// 1. 不需要参数,返回值为 5
() -> 5
// 2. 接收一个参数(数字类型),返回其2倍的值
x -> 2 * x
// 3. 接受2个参数(数字),并返回他们的差值
(x, y) -> x – y
// 4. 接收2个int型整数,返回他们的和
(int x, int y) -> x + y
// 5. 接受一个 string 对象,并在控制台打印,不返回任何值(看起来像是返回void)
(String s) -> System.out.print(s)
在Java8 中,方法引用是一种简化Lambda表达式的语法。它允许通过方法的名称来直接引用一个已经存在的方法,而不是像Lambda表达式那样定义个匿名函数。方法引用使代码更加简洁易读,而且可以提高代码的可维护性。
Java8 中共有四种方法引用的形式:
// Lambda表达式写法
Function parseIntLambda = str -> Integer.parseInt(str);
// 方法引用写法
Function parseIntReference = Integer::parseInt;
// Lambda表达式写法
BiPredicate startsWithLambda = (str, prefix) -> str.startsWith(prefix);
// 方法引用写法
BiPredicate startsWithReference = String::startsWith;
List names = Arrays.asList("Alice", "Bob", "Charlie");
// Lambda表达式写法
names.forEach(str -> System.out.println(str));
// 方法引用写法
names.forEach(System.out::println);
// Lambda表达式写法
Supplier> listSupplierLambda = () -> new ArrayList<>();
// 方法引用写法
Supplier> listSupplierReference = ArrayList::new;
Stream是一个功能强大的用于处理集合数据的工具。Stream API提供了一种更简洁、更易读的方式来操作集合,使得数据处理更具有函数式编程风格。
下面是Java8 Stream的基本用法和一些常用操作:
示例代码:
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class StreamExample {
public static void main(String[] args) {
List list = Arrays.asList("apple", "banana", "orange", "apple", "grape");
// 中间操作
List filteredList = list.stream()
.filter(fruit -> fruit.startsWith("a"))
.distinct()
.map(String::toUpperCase)
.sorted()
.collect(Collectors.toList());
System.out.println(filteredList); // Output: [APPLE]
// 终端操作
long count = list.stream()
.filter(fruit -> fruit.startsWith("a"))
.count();
System.out.println(count); // Output: 2
}
}