JAVA8 Stream流
2020-06-02 16:06:37来源:博客园 阅读 ()
JAVA8 Stream流
简介
Stream 是一个 Collection 的增强工具,可以对集合进行各种操作,而且可以很方便的写出并发程序,学习之前需要了解一些函数,可以看 JAVA8 Lambda表达式。常见的获取方式就是 Collection.stream()。
操作类型
操作类型分为三种
Intermediate(中间操作):可以多次使用,因为返回一个Stream。比如map(mapToInt, flatMap)、filter、sorted、limit、skip。Terminal(结束操作):使用后就会结束。比如forEach、sort、collect、min、count、findFirst、anyMatch。
中间操作都是惰性的,也就是延迟的,所以会产生副作用,关于副作用会在之后的章节详细说明。
创建
Stream 的类型有三种 IntStream,DoubleStream 和 LongStream,当然也可以使用 Stream<T>。
除了直接创建,还能通过 Collection 接口的 stream() 和 parallelStream() 创建,其中 parallelStream() 创建的流是并发、线程不安全且操作无序的,虽然它是并发的,但仍有可能在某些操作下变回串行的,例如 forEachOrdered,此外还需要保证数据源是线程安全的。
下面的代码展示了流的创建,第二行代码是取流中前三个元素在控制台输出,如果开启最后一行注释将会出现 java.lang.IllegalStateException 的异常,详细错误信息为 stream has already been operated upon or closed,所以创建的 Stream 仅能使用一次。
IntStream intStream = IntStream.of(1, 2, 3, 4);
intStream.limit(3).forEach(System.out::println);
//intStream.limit(1).forEach(System.out::println);
使用
JAVA8 中 Stream 接口中的操作有 filter、map、mapToInt、mapToLong、mapToDouble、flatMap、flatMapToInt、flatMapToLong、flatMapToDouble、distinct、sorted、peek、limit、skip、forEach、forEachOrdered、toArray、reduce、collect、min、max、count、anyMatch、allMatch、noneMatch、findFirst、findAny,方法很多,没见过的看注释、参数和返回值就懂了。
示例使用 List 接口 的 stream 方法创建 Stream,下面是示例所需要的数据。
//Get、Set、构造方法浪费空间,不粘贴了
public class Person {
//id
private Integer id;
//名字
private String name;
//年龄
private Integer age;
//组织
private String organization;
}
//数据初始化
List<Person> personList = new ArrayList<>();
personList.add(new Person(1, "灰原哀", 7, "帝丹小学"));
personList.add(new Person(2, "江户川柯南", 7, "帝丹小学"));
personList.add(new Person(3, "宫野明美", 24, "黑衣组织"));
personList.add(new Person(4, "赤井秀一", 27, "FBI"));
personList.add(new Person(5, "贝尔摩德", 29, "黑衣组织"));
下面是对 Stream 操作的两个个简单示例。
第一个将 personList 中 前 4 个、年龄为 7 的人提取出来,以组织和姓名为 key 和 value 组装成一个新的 Map,其中 Collectors.toMap 方法最后一个参数用于解决 key 冲突。
第二个获取 personList 中名字为安室透的第一个人。
Map<String, String> map = personList.stream().limit(4) //中间操作
.filter(person -> Objects.equals(person.getAge(), 7)) //中间操作
.collect(Collectors.toMap( // Collectors 类是随 Stream 一起引入的,即方便又好看,作用之一是收集元素到集合
Person::getOrganization, // map 的 key
Person::getName, // map 的 value
(old, now) -> old)); // 发生冲突的解决办法
Optional<Person> optional = personList.stream()
.filter(person->Objects.equals(person.getName(), "安室透")) //中间操作
.findFirst();
第二个方法返回值类型是 Optional<Person>,Optional 是 JAVA8 中引入的一个容器,可以使用 get() 获取容器中的值,但 optional 中并没有值,所以会抛出 java.util.NoSuchElementException,为了解决这个问题可以使用 orElse(),当容器中值为空时返回设定的默认值,除了 orElse 还有 orElseGet 和 orElseThrow。比如下面的这段代码返回了叫安室透的人。
// optional 在上一段代码中产生的对象
Person person = optional.orElse(new Person(7, "安室透", 29, "日本公安"));
副作用
对流的中间操作会产生副作用,结果是抛异常和数据的错误,它的来源有“干扰”和“有状态的 Lambda”。
- “干扰”就是在中间操作时修改了流的数据源。比如在
forEach(Consumer<? super T> action)中应该是消费数据,却给数据源添加了一个数据,结果是抛出了java.util.ConcurrentModificationException异常。 - “有状态的 Lambda”,当后面操作产生的结果会被前面的操作影响时,前面操作的
Lambda就被称作是有状态的。比如 有状态的 Lambda 的例子,例子中使用parallelStream()并发添加数据到parallelStorage中,结果就是parallelStorage中的数据顺序不可预测,因此称e -> { parallelStorage.add(e); return e; }是有状态的Lambda。
总结
本文没有深入介绍它的概念,只是简单介绍了 Stream 的使用和 Optional 容器,对于了解应该够了。
参考资料
为什么需要 Stream
Stream 副作用
Java 8 Stream 的终极技巧——Collectors 功能与操作方法详解
Java8(3)Stream类的collect方法详解
原文链接:https://www.cnblogs.com/hligy/p/13033718.html
如有疑问请与原作者联系
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
- 学习Java 8 Stream Api (4) - Stream 终端操作之 collect 2020-06-11
- Spring WebFlux 学习笔记 - (一) 前传:学习Java 8 Stream Ap 2020-06-11
- Java--Stream流详解 2020-06-10
- java8 stream的分组功能,具体时候是真的好用 2020-06-10
- XStream学习手册 2020-06-04
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash
