当 Java SE 8(又名核心 Java 8)在 2014 年被推出时,它引入了一些更改,从根本上影响了用它进行的编程 。这些更改中有两个紧密相连的部分:流 API 和函数式编程构造 。本文使用代码示例,从基础到高级特性,介绍每个部分并说明它们之间的相互作用 。
基础特性流 API 是在数据序列中迭代元素的简洁而高级的方法 。包 java.util.stream 和 java.util.function 包含了用于流 API 和相关函数式编程构造的新库 。当然,代码示例胜过千言万语 。
下面的代码段用大约 2,000 个随机整数值填充了一个 List:
Random rand = new Random2();List<Integer> list = new ArrayList<Integer>(); // 空 listfor (int i = 0; i < 2048; i++) list.add(rand.nextInt()); // 填充它
另外用一个 for 循环可用于遍历填充列表,以将偶数值收集到另一个列表中 。
流 API 提供了一种更简洁的方法来执行此操作:
List <Integer> evens = list .stream() // 流化 list .filter(n -> (n & 0x1) == 0) // 过滤出奇数值 .collect(Collectors.toList()); // 收集偶数值
这个例子有三个来自流 API 的函数:
- stream 函数可以将集合转换为流,而流是一个每次可访问一个值的传送带 。流化是惰性的(因此也是高效的),因为值是根据需要产生的,而不是一次性产生的 。
- filter 函数确定哪些流的值(如果有的话)通过了处理管道中的下一个阶段,即 collect 阶段 。filter 函数是 高阶的(higher-order),因为它的参数是一个函数 —— 在这个例子中是一个 lambda 表达式,它是一个未命名的函数,并且是 Java 新的函数式编程结构的核心 。
n -> (n & 0x1) == 0
箭头(一个减号后面紧跟着一个大于号)将左边的参数列表与右边的函数体分隔开 。参数 n 虽未明确类型,但也可以明确 。在任何情况下,编译器都会发现 n 是个 Integer 。如果有多个参数,这些参数将被括在括号中,并用逗号分隔 。在本例中,函数体检查一个整数的最低位(最右)是否为零,这用来表示偶数 。过滤器应返回一个布尔值 。尽管可以,但该函数的主体中没有显式的 return 。如果主体没有显式的 return,则主体的最后一个表达式即是返回值 。在这个例子中,主体按照 lambda 编程的思想编写,由一个简单的布尔表达式 (n & 0x1) == 0 组成 。
- collect 函数将偶数值收集到引用为 evens 的列表中 。如下例所示,collect 函数是线程安全的,因此,即使在多个线程之间共享了过滤操作,该函数也可以正常工作 。
IntStream // 整型流 .range(1, 2048) // 生成此范围内的整型流 .parallel() // 为多个线程分区数据 .filter(i -> ((i & 0x1) > 0)) // 奇偶校验 - 只允许奇数通过 .forEach(System.out::println); // 打印每个值
推荐阅读
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- c语言退出程序命令exit c语言exit函数用法
- 矩阵所有元素求和的公式 matlab矩阵求和函数
- c语言圆的面积编程 c语言阶乘函数怎么写
- 同位语从句经典例句 求同位语的具体用法和例句分析。
- spend的用法
- 并列连词 并列连词与从属连词的用法区别?
- 《如龙:极》鬼炎用法技巧解析攻略
- 对马岛之魂辅助功能有什么 对马之魂辅助功能用法介绍
- 团战经理骑士怎么用 团战经理骑士用法详解
- 团战经理狙击手好用吗 团战经理狙击手用法介绍