内容简介:Java 8 新增了一个新的抽象称为流Stream,个人感觉这个超级好用,尤其是业务开发,经常需要对数据列表进行处理的时候,用更少的代码、更优雅地实现功能。这个流式操作,更像是Linux中的管道命令'|',上一个操作的结果传送到下一个流程中继续处理,例如:在java代码实现
介绍
Java 8 新增了一个新的抽象称为流Stream,个人感觉这个超级好用,尤其是业务开发,经常需要对数据列表进行处理的时候,用更少的代码、更优雅地实现功能。
这个流式操作,更像是 Linux 中的管道命令'|',上一个操作的结果传送到下一个流程中继续处理,例如:
+--------------------+ +------+ +------+ +---+ +-------+ | stream of elements +-----> |filter+-> |sorted+-> |map+-> |collect| +--------------------+ +------+ +------+ +---+ +-------+ 复制代码
在 java 代码实现
String content = "hello,world,debug,the,world"; List<String> list = Arrays.asList(content.split(",")); List<String> filter = list.stream() .filter(temp -> temp.startsWith("w")) .map(temp -> temp.substring(0, 3)) .collect(Collectors.toList()); filter.forEach(System.out::print); 复制代码
什么是Stream
Stream(流)是一个来自数据源的元素队列并支持聚合操作
- 元素是特定类型的对象,形成一个队列。Java中的Stream并不会存储元素,而是按需计算。
- 数据源 流的来源可以是集合、数组、I/O Channel等
- 聚合操作 类似 SQL 语句,比如filter、map、reduce、find、match、sorted等
和以前的Collection操作不同,Stream还有两个基础特征:
- Pipelining :中间操作都会返回流对象本身。这样多个操作可以串联成一个管道。
- 内部迭代 :以前对集合遍历都是通过Iterator或者For-Each的方式,显示的在集合外部进行迭代。Stream提供了内部迭代的方式,通过访问者模式(Visitor)实现。
生成流
在Java8中,集合接口有两个方法生成流:
- stream() : 为集合创建串行流。
- parallelStream() - 为集合创建并行流。
这里要讲一下这两者的区别:
通俗点来说,一个是单线程、另一个是多线程。parallelStream是一个并行执行的流,通过默认的ForkJoinPool,可以提高多线程任务的速度。处理的过程会分而质之,将一个大任务切分成多个小任务,然后将结果合起来。(当然这也是一把双刃剑,在多线程的情况下,数据的并发访问需要关注,这也可以好好学一下,等之后再看吧~)
forEach
以前都是显示的使用循环,例如对一个集合进行打印: JDK7以前
for (int i = 0; i < list.size(); i++) { String temp = list.get(i); System.out.print(temp); } // 或者语法糖形式 for (String temp : list) { System.out.print(temp); } 复制代码
JDK8之后
list.forEach(System.out::println); 复制代码
对比一下,发现只需要一行代码就能实现~ 如果想在forEach中进行自定义的操作,可以创建一个类,实现Consumer函数接口,传递进去使用~
map
map方法用于映射每个元素到对应的结果:
Car car1 = Car.create(Car::new, "小汽车1"); Car car2 = Car.create(Car::new, "小汽车2"); List<Car> carList = Lists.newArrayList(car1, car2); List<String> nameList = carList.stream().map(Car::getName).collect(Collectors.toList()); // 还可以加入filter功能,先进行过滤,然后取出想要的字段组成新的列表 复制代码
Car类:
public class Car { private Integer id; private String name; public static Car create(final Supplier<Car> supplier, String name) { Car car = supplier.get(); car.setName(name); return car; } public static void collide(final Car car) { System.out.println("Collided " + car.toString()); } public void follow(final Car another) { System.out.println("Following the " + another.toString()); } public void repair() { System.out.println("Repaired " + this.toString()); } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "Car{}" + Thread.currentThread().getId() + getName(); } } 复制代码
filter
如其名,filter就是用来过滤的,根据特定的条件来过滤元素:
List<Integer> ints = Lists.newArrayList(1, 5, 6, 7, 10, 20, 31, 8, 9); long count = ints.stream().filter(number -> number > 10).count(); System.out.println(count); 复制代码
上面的例子是用来过滤出整数列表中,值大于10的数量。
limit
用来获取指定数量的流(类似于 MySQL 中的limit):
public void limitTest() { List<Integer> ints = Lists.newArrayList(1, 5, 6, 7, 10, 20, 31, 8, 9); ints.stream().limit(5).forEach(System.out::println); } 复制代码
sorted
用来对流进行排序,类似于Collections.sort(list, Comparator);
List<Integer> ints = Lists.newArrayList(1, 5, 6, 7, 10, 20, 31, 8, 9); ints.sort(Comparator.naturalOrder()); Car car1 = Car.create(Car::new, "小汽车1"); Car car2 = Car.create(Car::new, "小汽车2"); List<Car> carList = Lists.newArrayList(car1, car2); // 可以自定义 排序 的字段,如果需要更复杂的排序规则,可以在lambda中的statement进行编写 carList.sort(Comparator.comparing(Car::getName)); 复制代码
Collectors
Collectors类实现了很多规约操作,例如将流转换成集合和聚合元素。(一般用Collectors.toList()就够了)
//例如在一组对象中或者主键ID的列表可以这样写 public void collectorsTest() { List<Car> carList = Lists.newArrayList(); // 省略构建参数,获取列表中的主键ID列表 List<Integer> ids = carList.stream().map(Car::getId).collect(Collectors.toList()); } 复制代码
统计statistics
这个功能比较少用,还是学习记录一下吧。
public void statisticsTest() { List<Integer> ints = Lists.newArrayList(1, 5, 6, 7, 10, 20, 31, 8, 9); IntSummaryStatistics statistics = ints.parallelStream().mapToInt(x -> (int) x).summaryStatistics(); System.out.println("最大值 : " + statistics.getMax()); System.out.println("最小值 :" + statistics.getMin()); System.out.println("平均值 :" + statistics.getAverage()); System.out.println("总和 : " + statistics.getSum()); System.out.println("数量 :" + statistics.getCount()); } 复制代码
完整的测试代码
package com.example.demo; import com.example.demo.test.Car; import com.google.common.collect.Lists; import org.junit.Test; import java.util.Arrays; import java.util.Comparator; import java.util.IntSummaryStatistics; import java.util.List; import java.util.stream.Collectors; /** * @author JingQ at 2019/1/31 */ public class JDK8StreamTest { @Test public void buildStreamTest() { String content = "hello,world,debug,the,world"; List<String> list = Arrays.asList(content.split(",")); List<String> filter = list.stream() .filter(temp -> temp.startsWith("w")) .map(temp -> temp.substring(0, 3)) .collect(Collectors.toList()); filter.forEach(System.out::print); } @Test public void forEachTest() { String content = "hello,world,debug,the,world"; List<String> list = Arrays.asList(content.split(",")); list.forEach(System.out::println); } @Test public void mapTest() { Car car1 = Car.create(Car::new, "小汽车1"); Car car2 = Car.create(Car::new, "小汽车2"); List<Car> carList = Lists.newArrayList(car1, car2); List<String> nameList = carList.stream().map(Car::getName).collect(Collectors.toList()); // 还可以加入filter功能,先进行过滤,然后取出想要的字段组成新的列表 } /** * filter过滤 */ @Test public void filterTest() { List<Integer> ints = Lists.newArrayList(1, 5, 6, 7, 10, 20, 31, 8, 9); long count = ints.stream().filter(number -> number > 10).count(); System.out.println(count); } /** * limit 限制数量 */ @Test public void limitTest() { List<Integer> ints = Lists.newArrayList(1, 5, 6, 7, 10, 20, 31, 8, 9); ints.stream().limit(5).forEach(System.out::println); } @Test public void sortedTest() { List<Integer> ints = Lists.newArrayList(1, 5, 6, 7, 10, 20, 31, 8, 9); ints.sort(Comparator.naturalOrder()); Car car1 = Car.create(Car::new, "小汽车1"); Car car2 = Car.create(Car::new, "小汽车2"); List<Car> carList = Lists.newArrayList(car1, car2); // 可以自定义排序的字段,如果需要更复杂的排序规则,可以在lambda中的statement进行编写 carList.sort(Comparator.comparing(Car::getName)); } @Test public void collectorsTest() { List<Car> carList = Lists.newArrayList(); // 省略构建参数,获取列表中的主键ID列表 List<Integer> ids = carList.stream().map(Car::getId).collect(Collectors.toList()); } @Test public void statisticsTest() { List<Integer> ints = Lists.newArrayList(1, 5, 6, 7, 10, 20, 31, 8, 9); IntSummaryStatistics statistics = ints.parallelStream().mapToInt(x -> (int) x).summaryStatistics(); System.out.println("最大值 : " + statistics.getMax()); System.out.println("最小值 :" + statistics.getMin()); System.out.println("平均值 :" + statistics.getAverage()); System.out.println("总和 : " + statistics.getSum()); System.out.println("数量 :" + statistics.getCount()); } } 复制代码
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- 一文读懂监督学习、无监督学习、半监督学习、强化学习这四种深度学习方式
- 学习:人工智能-机器学习-深度学习概念的区别
- 统计学习,机器学习与深度学习概念的关联与区别
- 混合学习环境下基于学习行为数据的学习预警系统设计与实现
- 学习如何学习
- 深度学习的学习历程
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
区块链与人工智能:数字经济新时代
高航、俞学劢、王毛路 / 电子工业出版社 / 2018-7-23 / 80
《区块链与人工智能》是畅销书《区块链与新经济:数字货币2.0时代》全新修订升级版。本书是市场上为数不多的系统阐述区块链、人工智能技术与产业的入门级系统教程。从比特币到各类数字货币(代币),从基础原理到应用探讨,全景式呈现区块链与人工智能的发展脉络,既有历史的厚重感也有科技的未来感。本书的另一个亮点是系统整理了区块链创业地图,是一本关于区块链创业、应用、媒体的学习指南,以太坊创始人Vitalik专门......一起来看看 《区块链与人工智能:数字经济新时代》 这本书的介绍吧!