java.util.function中 Function, Supplier, Consumer, Predicate和其他函数式接口广泛用在支持lambda表达式的API中。
函数式接口为 lambda 表达式和方法引用提供目标类型。 每个函数式接口都有一个抽象方法,称为该函数式接口的函数式方法,lambda 表达式的参数和返回类型与之匹配或适应。 函数式接口可以在多个上下文中提供目标类型,例如赋值上下文、方法调用或强制转换上下文:
// Assignment context
Predicate
// Method invocation context
stream.filter(e -> e.getSize() > 10)…
// Cast context
stream.map((ToIntFunction) e -> e.getSize())…
- 此包中的接口是 JDK 使用的通用功能接口,也可供用户代码使用。 虽然它们没有确定 lambda 表达式可能适用的完整函数形状集,但它们提供了足够的内容来满足常见要求。 为特定目的提供的其他功能接口,例如java.io.FileFilter ,在使用它们的包中定义。
- 此包中的接口使用FunctionalInterface进行注释。 此注释不是编译器将接口识别为功能接口的要求,而只是帮助捕获设计意图并在识别意外违反设计意图时获得编译器的帮助。
- 函数式接口通常表示抽象概念,如函数、动作或谓词。 在记录功能接口或引用类型为功能接口的变量时,通常直接引用那些抽象概念,例如使用“此函数”而不是“此对象表示的函数”。 当 API 方法以这种方式接受或返回功能接口时,例如“将提供的功能应用于…”,这被理解为对实现适当功能接口的对象的非空引用,除非明确指定了潜在无效性。
这个包中的功能接口遵循一个可扩展的命名约定,如下:
- 有几种基本的函数形状,包括Function (从T到R一元函数)、 Consumer (从T到void一元函数)、 Predicate (从T到boolean一元函数)和Supplier (nilary 函数到R )。
- 函数形状具有基于它们最常用的方式的自然多样性。 基本形状可以通过 arity 前缀修改以指示不同的 arity,例如BiFunction (从T和U到R二元函数)。
- 还有其他派生函数形状可以扩展基本函数形状,包括UnaryOperator (扩展Function )和BinaryOperator (扩展BiFunction )。
- 功能接口的类型参数可以专门用于具有附加类型前缀的原语。 专门为同时具有通用返回类型和通用参数的类型的返回类型,我们前缀ToXxx ,如ToIntFunction 。 否则,类型参数是从左到右特化的,如DoubleConsumer或ObjIntConsumer 。 (类型前缀Obj用于表示我们不想特化这个参数,而是想继续下一个参数,如ObjIntConsumer 。)这些方案可以组合,如IntToDoubleFunction 。
- 如果所有参数都有专门化前缀,则可以省略 arity 前缀(如ObjIntConsumer )