这篇文章主要介绍了 Java 函数式编程 (六):Optional, 本文是系列文章的第 6 篇, 其它文章请参阅本文底部的相关文章, 需要的朋友可以参考下
选取单个元素
直觉来说选取单个元素肯定会比选取多个要简单得多, 不过这里也存在一些问题我们先看下一般的做法的问题是什么, 然后再看下如何用 lambda 表达式来解决它
我们先新建一个方法来查找一个以特定字母开头的元素, 然后打印出来
- public static void pickName(
- final List<String> names, final String startingLetter) {
- String foundName = null;
- for(String name : names) {
- if(name.startsWith(startingLetter)) {
- foundName = name;
- break;
- }
- }
这个方法简直跟刚过去的垃圾车一样臭不可闻我们先是新建了一个 foundName 的变量, 然后初始化成 null 这个就是恶臭之源我们不得不检查是否为空, 不然的话就会抛出一个 NullPointerException 或者一个错误响应我们还用了一个外部迭代器来循环列表, 如果找到了想要的元素之后还得跳出这个循环, 这又加重了原来的臭味: 基本类型偏执, 命令式风格, 可变性, 全齐活了一旦退出循环后, 我们还得先检查下结果, 然后才能进行打印这么点任务居然写了这么长的代码
我们来重新分析下这个问题我们只是希望能选出第一个匹配的元素, 并且能安全的处理不存在这样一个元素的情况我们来用 lambda 表达式重写一下这个 pickName 方法
- public static void pickName(
- final List<String> names, final String startingLetter) {
- final Optional<String> foundName =
- names.stream()
- .filter(name ->name.startsWith(startingLetter))
- .findFirst();
- System.out.println(String.format("A name starting with %s: %s",
- startingLetter, foundName.orElse("No name found")));
- }
JDK 里面一些强大的功能使得这段代码更得非常简洁首先我们用 filter 方法获取了所有满足条件的元素, 然后用了 Stream 类的 findFirst 方法选取出了返回集合的第一个元素这个方法返回的是一个 Optional 对象, 这就是 Java 里面官方认证的 null 变量的除臭剂
Optional 类非常有用, 你不用管结果是不是存在它使得我们免受空指针异常的烦恼, 并且更明确的指明了没有结果也是一种可能的结果通过 isPresent() 方法我们可以知道结果是不是存在, 想获取结果值的话可以使用 get() 方法我们还可以使用 (这个方法名能让你震惊)orElse 方法给它设置一个默认值, 就像前面代码里的那样
我们用之前一直在用的 friends 集合来验证下我们这个 pickName 方法
- pickName(friends, "N");
- pickName(friends, "Z");
这段代码选取出第一个匹配的元素, 如果没找到, 打印出一个友好的提示信息
- A name starting with N: Nate
- A name starting with Z: No name found
findFirst() 方法和 Optinal 类的结合使用减少了我们的代码量, 并且看起来感觉还不错不过 Optional 类的功能远不止这些比如说, 除了当对象不存在的时候能提供一个默认值外, 如果结果存在的话还可以用它来运行一段代码, 或者一个 lambda 表达式, 像这样:
foundName.ifPresent(name - >System.out.println("Hello" + name));
跟命令式的选取第一个匹配名字的代码比起来, 流式的优雅的函数式风格看真来更棒一些不过这个调用流的版本里是不是做的事情有点太多了 (译注: 先选出了所有匹配的再返回第一项)? 当然不是, 这些方法非常智能, 它们可以按需工作 (在后面 113 页的 Stream 的惰性求值中我们会深入探讨这点)
选取单个元素的例子展示了 JDK 库更多强大的功能, 下面我们来看下 lambda 表达式如何根据一个集合, 来求出一个想要的值
来源: http://www.phperz.com/article/16/0721/235767.html