169it科技资讯
169it -->


当前位置:  编程技术>java/j2ee

Java函数式编程(六):Optional

    来源: 互联网  发布时间:2014-11-08

选取单个元素

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


    
相关技术文章:
    ▪Java函数式编程(七):MapReduce

     译注:map(映射)和reduce(归约,化简)是数学上两个很基础的概念,它们很早就出现在各类的函数编程语言里了,直到2003年Google将其发扬光大,运用到分布式系统中进行并行计算后,这个组合的名字才开始在计算机界大放异彩(那些函数式粉可能并不这么认为)。本文我们会看到Java 8在摇身一变支持函数式编程后,map和reduce组合的首次亮相(这里只是初步介绍,后续还会有针对它们的专题)。 对集合进行归约 现在为止我们已经介绍了几个操作集合的新技巧了:查找匹配元素,查找单个元素,集合转化。这些操作有一个共同点,它们都是......


    ▪Java函数式编程(八):字符串及方法引用

     第三章 字符串,比较器和过滤器 JDK引入的一些方法对写出函数式风格的代码很有帮助。JDK库里的一些的类和接口我们已经用得非常熟悉了,比如说String,为了摆脱以前习惯的那种老的风格,我们得主动寻找机会来使用这些新的方法。同样,当我们需要用到只有一个方法的匿名内部类时,我们现在可以用lambda表达式来替换它了,不用再像原来那样写的那么繁琐了。 本章我们会使用lambda表达式和方法引用来遍历字符串,实现Comparator接口,查看目录中的文件,监视文件及目录的变更。上一章中介绍的一些方法还将继续出现在这里,来帮助我们......


    ▪Java函数式编程(九):Comparator

     实现Comparator接口 Comparator接口的身影在JDK库中随处可见,从查找到排序,再到反转操作,等等。Java 8里它变成了一个函数式接口,这样的好处就是我们可以使用流式语法来实现比较器了。 我们用几种不同的方式来实现一下Comparator,看看新式语法的价值所在。你的手指头会感谢你的,不用实现匿名内部类少敲了多少键盘啊。 使用Comparator进行排序 下面这个例子将使用不同的比较方法,来将一组人进行排序。我们先来创建一个Person的JavaBean。 代码如下: public......


 
最新技术文章:
    ▪Java中使用开源库JSoup解析HTML文件实例

     HTML是WEB的核心,互联网中你看到的所有页面都是HTML,不管它们是由JavaScript,JSP,PHP,ASP或者是别的什么WEB技术动态生成的。你的浏览器会去解析HTML并替你去渲染它们。不过如果你需要自己在Java程序中解析HTML文档并查找某些元素,标签,属性或者检查某个特定的元素是否存在的话,那又该如何呢?如果你已经使用Java编程多年了,我相信你肯定试过去解析XML,也使用过类似DOM或者SAX这样的解析器,不过很有可能你从未进行过任何的HTML解析的工作。更讽刺的是,在Java应用中,很少会有需要你去解析HTML文档的时候,这里并不包括Servlet或者其它的Java WEB技术。更糟糕......


    ▪Java函数式编程(一):你好,Lambda表达式

     第一章 你好,lambda表达式! 第一节 Java的编码风格正面临着翻天覆地的变化。 我们每天的工作将会变成更简单方便,更富表现力。Java这种新的编程方式早在数十年前就已经出现在别的编程语言里面了。这些新特性引入Java后,我们可以写出更简洁,优雅,表达性更强,错误更少的代码。我们可以用更少的代码来实现各种策略和设计模式。 在本书中我们将通过日常编程中的一些例子来探索函数式风格的编程。在使用这种全新的优雅的方式进行设计编码之前,我们先来看下它到底好在哪里。 改变了你的思......


    ▪Java函数式编程(二):集合的使用

     第二章:集合的使用 我们经常会用到各种集合,数字的,字符串的还有对象的。它们无处不在,哪怕操作集合的代码要能稍微优化一点,都能让代码清晰很多。在这章中,我们探索下如何使用lambda表达式来操作集合。我们用它来遍历集合,把集合转化成新的集合,从集合中删除元素,把集合进行合并。 遍历列表 遍历列表是最基本的一个集合操作,这么多年来,它的操作也发生了一些变化。我们使用一个遍历名字的小例子,从最古老的版本介绍到现在最优雅的版本。 用下面的代码我们很容易创建一个不可变的名字的......


 


站内导航:


特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

©2012-2017,169IT.COM,E-mail:www_169it_com#163.com(请将#改为@)

浙ICP备11055608号