javarandom函数用法 java随机函数怎么写( 五 )

以下是一些函数组合的样例:
int arg = 5;doubled.compose(squared).applyAsInt(arg); // 5 求 2 次方后乘 2:50tripled.compose(doubled).applyAsInt(arg); // 5 乘 2 后再乘 3:30doubled.andThen(squared).applyAsInt(arg); // 5 乘 2 后求 2 次方:100squared.andThen(tripled).applyAsInt(arg); // 5 求 2 次方后乘 3:75函数组合可以直接使用 lambda 表达式实现,但是引用使代码更简洁 。
构造器引用构造器引用是另一种函数式编程构造,而这些引用在比 lambda 和方法引用更微妙的上下文中非常有用 。再一次重申,代码示例似乎是最好的解释方式 。
考虑这个 POJO 类:
public class BedRocker { // 基岩的居民    private String name;    public BedRocker(String name) { this.name = name; }    public String getName() { return this.name; }    public void dump() { System.out.println(getName()); }}该类只有一个构造函数,它需要一个 String 参数 。给定一个名字数组,目标是生成一个 BedRocker 元素数组,每个名字代表一个元素 。下面是使用了函数式结构的代码段:
String[] names = {"Fred", "Wilma", "Peebles", "Dino", "Baby Puss"};Stream<BedRocker> bedrockers = Arrays.asList(names).stream().map(BedRocker::new);BedRocker[] arrayBR = bedrockers.toArray(BedRocker[]::new);Arrays.asList(arrayBR).stream().forEach(BedRocker::dump);在较高的层次上,这个代码段将名字转换为 BedRocker 数组元素 。具体来说,代码如下所示 。Stream 接口(在包 java.util.stream 中)可以被参数化,而在本例中,生成了一个名为 bedrockers 的 BedRocker 流 。
Arrays.asList 实用程序再次用于流化一个数组 names,然后将流的每一项传递给 map 函数,该函数的参数现在是构造器引用 BedRocker::new 。这个构造器引用通过在每次调用时生成和初始化一个 BedRocker 实例来充当一个对象工厂 。在第二行执行之后,名为 bedrockers 的流由五项 BedRocker 组成 。
这个例子可以通过关注高阶 map 函数来进一步阐明 。在通常情况下,一个映射将一个类型的值(例如,一个 int)转换为另一个相同类型的值(例如,一个整数的后继):
map(n -> n + 1) // 将 n 映射到其后继然而,在 BedRocker 这个例子中,转换更加戏剧化,因为一个类型的值(代表一个名字的 String)被映射到一个不同类型的值,在这个例子中,就是一个 BedRocker 实例,这个字符串就是它的名字 。转换是通过一个构造器调用来完成的,它是由构造器引用来实现的:
map(BedRocker::new) // 将 String 映射到 BedRocker传递给构造器的值是 names 数组中的其中一项 。
此代码示例的第二行还演示了一个你目前已经非常熟悉的转换:先将数组先转换成 List,然后再转换成 Stream:
Stream<BedRocker> bedrockers = Arrays.asList(names).stream().map(BedRocker::new);第三行则是另一种方式 —— 流 bedrockers 通过使用数组构造器引用 BedRocker[]::new 调用 toArray 方法:
BedRocker[ ] arrayBR = bedrockers.toArray(BedRocker[]::new);该构造器引用不会创建单个 BedRocker 实例,而是创建这些实例的整个数组:该构造器引用现在为 BedRocker[]:new,而不是 BedRocker::new 。为了进行确认,将 arrayBR 转换为 List,再次对其进行流式处理,以便可以使用 forEach 来打印 BedRocker 的名字 。
FredWilmaPeeblesDinoBaby Puss该示例对数据结构的微妙转换仅用几行代码即可完成,从而突出了可以将 lambda,方法引用或构造器引用作为参数的各种高阶函数的功能 。
柯里化(Currying)柯里化函数是指减少函数执行任何工作所需的显式参数的数量(通常减少到一个) 。(该术语是为了纪念逻辑学家 Haskell Curry 。)一般来说,函数的参数越少,调用起来就越容易,也更健壮 。(回想一下一些需要半打左右参数的噩梦般的函数!)因此,应将柯里化视为简化函数调用的一种尝试 。java.util.function 包中的接口类型适合于柯里化,如以下示例所示 。

推荐阅读