第三章 字符串,比较器和过滤器
JDK引入的一些方法对写出函数式风格的代码很有帮助。JDK库里的一些的类和接口我们已经用得非常熟悉了,比如说String,为了摆脱以前习惯的那种老的风格,我们得主动寻找机会来使用这些新的方法。同样,当我们需要用到只有一个方法的匿名内部类时,我们现在可以用lambda表达式来替换它了,不用再像原来那样写的那么繁琐了。
本章我们会使用lambda表达式和方法引用来遍历字符串,实现Comparator接口,查看目录中的文件,监视文件及目录的变更。上一章中介绍的一些方法还将继续出现在这里,来帮助我们更好的完成这些任务。你学到的这些新技术有助于将冗长繁琐的代码变得简洁,不仅能快速实现而且还易于维护。
遍历字符串
chars()方法是String类里的一个新方法,它是CharSequence接口的一部分。想要快速遍历String的字符序列的话,它是一个很有用的工具。有了这个内部迭代器,我们可以方便的操作字符串中的各个字符。先用它来处理一个字符串试试。在这里顺便介绍方法引用的几种使用方式。
final String str = "w00t"; str.chars() .forEach(ch -> System.out.println(ch));
119 48 48 116
前面的代码中我们创建了一个lambda表达式,作为forEach方法的入参。它只是简单地把参数传给了一个println()方法。由于这个操作很常见,我们可以借助Java编译器来对这段代码进行简化。就像在25页的使用方法引用中那样,用一个方法引用来代替它,让编译器来帮我们做参数路由。
我们已经看到如何创建一个实例方法的方法引用了。比如,name.toUpperCase()方法,方法引用就是String::toUpperCase。而下面这个例子中,我们调用的是静态引用System.out的一个实例方法。方法引用的两个冒号左边,可以是一个类名或者表达式。有了这个灵活性,我们可以很容易创建一个println()方法的引用,就像下面这样。
str.chars() .forEach(System.out::println);
(译注:其实主要是两种场景,同样是传递了一个方法引用,一个是把遍历的对象,当然方法调用的目标对象,比如name.toUpperCase,另外一种是作为方法调用的参数,比如System.out.println(name).)
用了方法引用之后代码简洁多了,不过我们得去深入了解下它是如何运行的。一旦我们熟悉了方法引用,就能自己想明白参数路由这些事了。
尽管这个例子中的代码已经够简洁的了,但是输出还是不如人意。我们想看到的是字母结果却出现了数字。为了解决这个问题,我们来写个方法将int输出成字母。
private static void printChar(int aChar) { System.out.println((char)(aChar)); }
str.chars() .forEach(IterateString::printChar);
w 0 0 t
str.chars() .mapToObj(ch -> Character.valueOf((char)ch)) .forEach(System.out::println);
str.chars() .filter(ch -> Character.isDigit(ch)) .forEach(ch -> printChar(ch));
0 0
str.chars() .filter(Character::isDigit) .forEach(IterateString::printChar);
实例方法和静态方法的引用看起来都一样:比方说String::toUpperCase和Character::isDigit。编译器会判断方法是实例方法还是静态方法,来决定如何路由参数。如果是实例方法,它会将生成方法的入参用作方法调用的目标对象,比如 parameter,toUpperCase();(当然也有例外,比如方法调用的目标对象已经指定了,像System::out.println())。另外如果是静态方法的话,生成方法的入参就会作为这个引用的方法的参数,比如Character.isDigit(parameter)。152页的附录2,有详细的方法引用的使用方法及语法说明。
尽管方法引用用起来很方便,但还有一个问题——方法命名冲突导致的二义性 。如果匹配的方法既有实例方法也有静态方法,由于方法存在歧义编译器会报错。比如这么写,Double::toString,我们其实是想要把一个double类型转化成字符串,但编译器就不知道到底是该调用public String toString()的实例方法好,还是去调用public static String toString(double)方法,因为两个方法都是Double类的。如果你碰到这样的情况,别灰心,就用lambda表达式来完成就好了。
一旦我们适应了函数式编程,我们就可以在lambda表达式和方法引用之间随心所欲地来回切换了。
本节中我们用了Java 8中的一个新方法来遍历字符串。下面我们来看下Comparator接口又有了哪些改进。
我有一个名为的类,其中有一个字符串数组: 我的当前活动代码: 在中出现错误。单击时,如何将文本更改为字符串之一?
本文向大家介绍ThinkPHP字符串函数及常用函数汇总,包括了ThinkPHP字符串函数及常用函数汇总的使用技巧和注意事项,需要的朋友参考一下 本文汇总了ThinkPHP的字符串处理函数及其他一些常用函数,可供开发人员参考使用。详情如下: 获取客户端的IP地址 $str:要截取的字符串 $start=0:开始位置,默认从0开始 $length:截取长度 $charset=”utf-8″:字符编码,
问题内容: 如何在Java中模拟函数式编程,特别是如何将函数映射到项目集合? 什么是最冗长和尴尬的方法? 问题答案: 在Java之前,所有的函数式编程尝试在Java中都会有些 冗长 和/或 笨拙 ,直到Java 8。 最 直接的 方法是提供一个接口(例如Guava的这种形式),并提供采用和调用该接口的各种方法(例如我认为您的方法应该执行的操作)。 不好的事情是,您需要使用匿名内部类来实现并经常这样
本文向大家介绍Java字符串方法,包括了Java字符串方法的使用技巧和注意事项,需要的朋友参考一下 字符串类在Java中有很多方法可以处理字符串,查找长度,格式化字符串,连接等。 以下是Java中的一些字符串方法- 序号 方法与说明 1 char charAt(int index) 返回指定索引处的字符。 2 int compareTo(Object o) 将此字符串与另一个对象进行比较。 3 i
本文向大家介绍Python字符串函数strip()原理及用法详解,包括了Python字符串函数strip()原理及用法详解的使用技巧和注意事项,需要的朋友参考一下 strip:用于移除字符串头尾指定的字符(默认为空格)或字符序列。注意:该方法只能删除开头或是结尾的字符,不能删除中间部分的字符。 语法:str.strip([chars]) str = "*****this is **string**
本文向大家介绍整理Java编程中字符串的常用操作方法,包括了整理Java编程中字符串的常用操作方法的使用技巧和注意事项,需要的朋友参考一下 字符 一般情况下,当我们处理字符时,我们用原始数据类型 char。 示例 然而在开发中,我们会遇到需要使用对象而不是原始数据类型的情况。为了达到这个需求。Java 为原始数据类型 char 提供了包装类 Character。 Character 类为操控字符提