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


下面 Number 类的实例用 EVEN 或 ODD 表示有奇偶校验的整数值:
public class Number {    enum Parity { EVEN, ODD }    private int value;    public Number(int n) { setValue(n); }    public void setValue(int value) { this.value = https://www.yf-zs.com/shuma/value; } public int getValue() { return this.value; } public Parity getParity() { return ((value & 0x1) == 0) ? Parity.EVEN : Parity.ODD; } public void dump() { System.out.format("Value: %2d (parity: %s)\n", getValue(),                          (getParity() == Parity.ODD ? "odd" : "even"));    }}下面的代码演示了用 Number 流进行 map/reduce 的情形,从而表明流 API 不仅可以处理 int 和 float 等基本类型,还可以处理程序员自定义的类类型 。
在下面的代码段中,使用了 parallelStream 而不是 stream 函数对随机整数值列表进行流化处理 。与前面介绍的 parallel 函数一样,parallelStream 变体也可以自动执行多线程 。
final int howMany = 200;Random r = new Random();Number[] nums = new Number[howMany];for (int i = 0; i < howMany; i++) nums[i] = new Number(r.nextInt(100));List<Number> listOfNums = Arrays.asList(nums);  // 将数组转化为 listInteger sum4All = listOfNums    .parallelStream()           // 自动执行多线程    .mapToInt(Number::getValue) // 使用方法引用,而不是 lambda    .sum();                     // 将流值计算出和值System.out.println("The sum of the randomly generated values is: " + sum4All);高阶的 mapToInt 函数可以接受一个 lambda 作为参数,但在本例中,它接受一个方法引用,即 Number::getValue 。getValue 方法不需要参数,它返回给定的 Number 实例的 int 值 。语法并不复杂:类名 Number 后跟一个双冒号和方法名 。回想一下先前的例子 System.out::println,它在 System 类中的 static 属性 out 后面有一个双冒号 。
方法引用 Number::getValue 可以用下面的 lambda 表达式替换 。参数 n 是流中的 Number 实例中的之一:
mapToInt(n -> n.getValue())通常,lambda 表达式和方法引用是可互换的:如果像 mapToInt 这样的高阶函数可以采用一种形式作为参数,那么这个函数也可以采用另一种形式 。这两个函数式编程结构具有相同的目的 —— 对作为参数传入的数据执行一些自定义操作 。在两者之间进行选择通常是为了方便 。例如,lambda 可以在没有封装类的情况下编写,而方法则不能 。我的习惯是使用 lambda,除非已经有了适当的封装方法 。
当前示例末尾的 sum 函数通过结合来自 parallelStream 线程的部分和,以线程安全的方式进行归约 。但是,程序员有责任确保在 parallelStream 调用引发的多线程过程中,程序员自己的函数调用(在本例中为 getValue)是线程安全的 。
最后一点值得强调 。lambda 语法鼓励编写 纯函数(pure function),即函数的返回值仅取决于传入的参数(如果有);纯函数没有副作用,例如更新一个类中的 static 字段 。因此,纯函数是线程安全的,并且如果传递给高阶函数的函数参数(例如 filter 和 map )是纯函数,则流 API 效果最佳 。
对于更细粒度的控制,有另一个流 API 函数,名为 reduce,可用于对 Number 流中的值求和:
Integer sum4AllHarder = listOfNums    .parallelStream()                           // 多线程    .map(Number::getValue)                      // 每个 Number 的值    .reduce(0, (sofar, next) -> sofar + next);  // 求和此版本的 reduce 函数带有两个参数,第二个参数是一个函数: