您的位置:首页 > 编程语言 > Java开发

Java8 Stream 初探(一)

2016-05-22 15:23 429 查看

Java8 Stream 初探(一)

Java8是自java5发布以来变动最大的一个版本,添加了一系列新特性,其中最引人注目的个人觉得要属于lambda表达式,新版本的位于java.util.stream API,函数是编程等,之前一直没有研究过,最近有空抽个时间,研究了下关于stream的一些常用方法,越来越觉得编程中使用stream的便利性,下面会给出一些常用的例子做一些说明讲解,算是对自己这段时间研究stream的一个补充。

鉴于网络上对于stream以及lambda的一些入门介绍已经比较详细了,本文不打算从0开始讲解lambda以及stream,更多的是就我所学的东西写一些实例出来,毕竟我在看这一块资料的时候,很多讲解缺乏一些常见的应用实例,看以下示例之前,读者需要先了解什么是lambda以及stream,想了解这部分的基础知识,不放可以看下以下的两个链接

lambda介绍:http://news.oneapm.com/java-8-oneapm-lambda

stream介绍:http://ifeve.com/stream

个人觉得上述两篇博文写的挺好的,浅显易懂,尤其是第二篇讲述stream,借助图表的方式讲的特别透彻。

ok,下面进入正题,一些示例以及常见的使用场景

场景1:

拿到一个List列表,将其转换为以逗号分隔的字符串,这种转换方式尤以在代码发送http请求的时候经常遇到

来看看常见的解决此方案的方法:

public static String createStringFromIds(List<String> ids){
StringBuilder sb = new StringBuilder();
for(Integer id:ids){
sb.append(id).append(",");
}
String idStr = sb.toString();
return idStr.subString(0,idStr.len()-1);
}


写一个方法,对list列表做一个遍历,然后append到一个StringBuilder中,最后做一个字符截取操作,下面来看看用Java8 stream 的实现方式:

String idStr=strList.stream().collect(Collectors.joining(","));


一行代码,是不是简介了很多,而且还不用做最后哪一步的字符串截取操作,无论从代码行数,整洁程度,可读性都比上面哪一种方式好太多了,(在jdk1.8之前想实现上述代码可以借助于google 的guava类库,用Joiner实现类似方式,不过1.8之后jdk原生就支持了这种操作方式,何乐而不为呢,下述一些其他的示例基本都可以借助guava实现,感兴趣的同学可以去研究下guava的用法)。

场景2

List strIds为一个String类型的id列表,我们的下层接口参数列表类型为List类型,来看看常见解决方案:

public static List<Integer> str2IntegerList(List<String> strs){
List<Integer> list = new ArrayList<>();
for(String str:strs){
list.add(Integer.parseInt(str));
}
return list;
}


Stream api 实现方式:

List<Integer> integers = strList.stream().map((str)->Integer.parseInt(str)).collect(Collectors.toList());


跟场景1类似,同样的一行代码完成了我们之前3-4行代码的内容

场景三:取某个对象列表里面的单个属性

解决方案一:

public class Foo{
public int id;
public String name;
public int age;
public Date createTime;
}


上述例子为一个简单的pojo类,为了简便起见,直接将属性写成了public方式,懒得写get/set方法了,原理是一样的

public static List<Integer> getFooIds(List<Foo> foos){
List<Integer> ids = new ArrayList<>();
for(Foo foo:foos){
ids.add(foo.id);
}
return ids;
}


Stream API:

List<Foo> foos = getFoosFromSomeWhere();

List<Integer> ids = foos.stream().map((foo)->foo.id).collect(Collectors.toList());


休息一下,我们看看上述的三个示例,我相信绝大多数的java开发人员都曾经碰到过类似的问题,对比看,三个stream api示例中,出现最多的几个方法:stream(),map(),collect(),大致坐下说明:

stream():创建一个stream流(stream基本都是基于java collection对象创建的)

map():类型转换,将一个给定类型的实例转换为另外一个实例,上述示例中String->int,Foo->int等,stream可以接多个map方法,示例二中的String-int你甚至也可以这样写(只要你愿意。。。):

List<Integer> integers = strList.stream().map((str)->Integer.parseInt(str)).map((i)->i+"").map((str)->Integer.parseInt(str)).collect(Collectors.toList());


collect():字面意思是收集的意思,可以将其简单的理解为将前面转换过后的对象进行收集,jdk提供一个Collectors类,里面有很多预定义好的”收集器”。

ok,今天先写到这,后续会逐步添加一些其他功能的示例,常见的方法有filter ,map,collect,groupby等等操作,这些操作更多的出现于关系数据库中,jdk1.8之前的集合类要实现这些功能需要自己写业务逻辑去实现,不过这些操作在jdk1.8中,绝大多数操作都可以借助于stream api方式取实现。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: