java 8 stream api 中有两个方法map和flatMap非常实用,应用场景也非常广泛,能极大提升编程效率。下面我们详细介绍一下这两个方法的用法。
map方法
我们来看个示例:把一个整数列表转换成字符串列表,java 8之前常用的实现方法如下
List
这种写法比较符合直觉,但略显繁琐。如果用java 8的stream api的map方法则可以把这个过程变的非常简洁
List
map方法接受一个lambda表达式,这个表达式是一个函数,输入类型是集合元素的类型,输出类型是任意类型
it -> Integer.toString(it)
在示例中就是将集合中的整数元素逐个转换成字符串类型。这种写法和常规的编程思路不同,却有点像SQL
select
这条SQL语句读取一张表的id字段,id是int类型,我们将他转换成字符类型,实现方法如下
select cast(id as CHAR(10)) as id from table1
SQL中的select对应的是map方法
cast(id as CHAR(10)) 对应的就是 it -> Integer.toString(it)
我们还可以用map实现很多效果,比如转换成符合要求的bool列表
List
或者转换成某种对象列表
public
都可以非常迅速的实现,和那些流水账式的代码告别
List
其实这种写法就是函数式编程的声明性编程,将代码写成表达式类型。而我们常用的SQL语言天生就是函数式语言。
flatMap方法
我们把需求扩展下
先定义两个类型
private
KlassGroup类中定义了一个Klass类的列表
现在我们有一组KlassGroup对象
List
需要将每个KlassGroup对象中的那些Klass类取出来,放到一个ArrayList里面,得到一个List<Klass>。我们尝试着用map方法来实现
List
哈,不成功,我们想要的结果是List<Klass>,现在得到了 List<List<Klass>>。当然,我们可以轻而易举的解决这个问题
List
但是这种套了两层for循环的代码太丑陋了。面对这种需求,flatMap可以大展身手了
List
一行代码就实现了
stream api 的 flatMap方法接受一个lambda表达式函数, 函数的返回值必须也是一个stream类型,flatMap方法最终会把所有返回的stream合并,map方法做不到这一点,如果用map去实现,会变成这样一个东西
List
flatMap的思路在其他语言中也有体现,比如C# Linq中的 SelectMany 方法,F# 中的 List.collect方法都有同样的作用。用函数式编程的说法,他们都实现了 monad,当然,monad这个概念很难是通俗的描述清楚,此文中就不展开了。
java 8 stream api 中各方法可以极大的简化集合操作,带来大幅度的编码效率提升,如果是java 8及以上的版本,一定要优先使用,stream api绝对是java中史诗级的工作效率提升利器。