欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Java函数式编程(六):Optional

程序员文章站 2024-03-01 16:22:28
选取单个元素 直觉来说选取单个元素肯定会比选取多个要简单得多,不过这里也存在一些问题。我们先看下一般的做法的问题是什么,然后再看下如何用lambda表达式来解决它。 我...

选取单个元素

直觉来说选取单个元素肯定会比选取多个要简单得多,不过这里也存在一些问题。我们先看下一般的做法的问题是什么,然后再看下如何用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表达式如何根据一个集合,来求出一个想要的值。