「Java」Stream新特性,鲜有人用,却能简化你的代码

Java8发布都好长一段时间了,前几个月Java10都发布了,Java11也快出来了;但小编发现,身边的javaer都是使用的JDK7或以下的版本,这不能怪大家;只能说,公司的产品都是JDK的稳定版本的,毕竟好多都是老产品,升级一个产品的JDK可不是换个数字那么简单;不过作为一个javaer,跟上java的新特性还是很重要的,说不定哪天就用上了呢?那么今天小编给大家介绍的就是Java8的新特性之一Stream。

先睹为快

代码如下:

List strings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl");

List filtered = strings.stream().filter(string -> !string.isEmpty()).collect(Collectors.toList());

System.out.println("原集合:"+strings.toString());

System.out.println("处理后的集合"+filtered.toString());

输出如下:

原集合:[abc, , bc, efg, abcd, , jkl]

处理后的集合[abc, bc, efg, abcd, jkl]

什么是Stream?

首先要说的是,不要被它的名称骗了,这里的Stream跟JAVA I/O中的InputStream和OutputStream是两个不同的概念。

Stream是一种可供流式操作的数据视图,有些类似数据库中视图的概念,它不改变源数据集合,如果对其进行改变的操作它会返回一个新的数据集合。

总的来讲它有三大特性:在之后我们会对照着详细说明

  1. stream不存储数据
  2. stream不改变源数据
  3. stream的延迟执行特性

Stream的优点

  1. 对JAVA集合(Collection)对象功能的增强,方便对集合进行各类操作(过滤、求最大值、最小值、统计等);
  2. 更加高效,提供串行和并行两种模式,并行模式利用了Java中的fork/join框架技术,能充分利用多核处理器,提高程序并发性;

Stream的操作分类

「Java」Stream新特性,鲜有人用,却能简化你的代码

Stream操作分类

Stream上的所有操作分为两类:中间操作和结束操作,中间操作只是一种标记,只有结束操作才会触发实际计算。

  • 中间操作又可以分为无状态的和有状态的:无状态中间操作是指元素的处理不受前面元素的影响,而有状态的中间操作必须等到所有元素处理之后才知道最终结果,比如排序是有状态操作,在读取所有元素之前并不能确定排序结果;
  • 结束操作又可以分为短路操作和非短路操作:短路操作是指不用处理全部元素就可以返回结果,比如找到第一个满足条件的元素。之所以要进行如此精细的划分,是因为底层对每一种情况的处理方式不同。

常用中间件

filter:过滤流,过滤流中的元素,返回一个符合条件的Stream

map:转换流,将一种类型的流转换为另外一种流。(mapToInt、mapToLong、mapToDouble 返回int、long、double基本类型对应的Stream)

flatMap:简单的说,就是一个或多个流合并成一个新流。(flatMapToInt、flatMapToLong、flatMapToDouble 返回对应的IntStream、LongStream、DoubleStream流。)

distinct:返回去重的Stream。

sorted:返回一个排序的Stream。

peek:主要用来查看流中元素的数据状态。

limit:返回前n个元素数据组成的Stream。属于短路操作

skip:返回第n个元素后面数据组成的Stream。

结束操作

forEach: 循环操作Stream中数据。

toArray: 返回流中元素对应的数组对象。

reduce: 聚合操作,用来做统计。

collect: 聚合操作,封装目标数据。

min、max、count: 聚合操作,最小值,最大值,总数量。

anyMatch: 短路操作,有一个符合条件返回true。

allMatch: 所有数据都符合条件返回true。

noneMatch: 所有数据都不符合条件返回true。

findFirst: 短路操作,获取第一个元素。

findAny: 短路操作,获取任一元素。

forEachOrdered: 暗元素顺序执行循环操作。

举个栗子

map例子

代码如下:

List peopleList = new ArrayList();

peopleList.add(new People("张三", 64, 178, 26,"程序员"));

peopleList.add(new People("李四", 58, 177, 28, "会计师"));

peopleList.add(new People("王五", 44, 158, 20, "司机"));

peopleList.add(new People("李敏", 45, 163, 23, "HR"));

peopleList.add(new People("赵六", 76, 187, 25, "翻译"));

peopleList.add(new People("余天", 75, 176, 68, "退休"));

//1、只取出该集合中所有姓名组成一个新集合

List nameList=peopleList.stream().map(People::getName).collect(Collectors.toList());

System.out.println(nameList.toString());

//2、只取出该集合中所有岁数组成一个新集合

List idList=peopleList.stream().mapToInt(People::getAge).boxed().collect(Collectors.toList());

System.out.println(idList.toString());

//3、list转map,key值为name,value为People对象

Map peoplemap = peopleList.stream().collect(Collectors.toMap(People::getName, people -> people));

System.out.println(peoplemap.toString());

//4、list转map,key值为name,value为job

Map namemap = peopleList.stream().collect(Collectors.toMap(People::getName, People::getJob));

System.out.println(namemap.toString());

输出如下:

[张三, 李四, 王五, 李敏, 赵六, 余天]

[26, 28, 20, 23, 25, 68]

{李四=com.conta.bean.People@4dd8dc3, 张三=com.conta.bean.People@6d03e736, 王五=com.conta.bean.People@568db2f2, 余天=com.conta.bean.People@378bf509, 赵六=com.conta.bean.People@5fd0d5ae, 李敏=com.conta.bean.People@2d98a335}

{李四=会计师, 张三=程序员, 王五=司机, 余天=退休, 赵六=翻译, 李敏=HR}

filter例子

代码如下:

List peopleList = new ArrayList();

peopleList.add(new People("张三", 64, 178, 26,"程序员"));

peopleList.add(new People("李四", 58, 177, 28, "会计师"));

peopleList.add(new People("王五", 44, 158, 20, "司机"));

peopleList.add(new People("李敏", 45, 163, 23, "HR"));

peopleList.add(new People("赵六", 76, 187, 25, "翻译"));

peopleList.add(new People("余天", 75, 176, 68, "退休"));

//1、查找年龄大于25岁的人数

long count= peopleList.stream().filter(p->p.getAge()>25).count();

System.out.println(count);

//2、查找年龄大于25岁,身高170以上的人数

List ageList=peopleList.stream().filter(p->p.getAge()>25).filter(p->p.getHeight()>170).collect(Collectors.toList());

System.out.println(ageList.size());

输出如下:

3

3

篇幅有限,这里就不将每个API一一举例了,想要了解更多的朋友,可以点击链接深入。


分享到:


相關文章: