---
id: "2019-03-25-20-52"
date: "2019/03/25 20:52"
title: "java8新增的stream流库，看这篇就够了"
tags: ["java", "stream"]
categories:
  - "java"
  - "java基础"
---

# 什么是流

流提供了一种在比集合更高的概念级别上指定计算的数据视图。通过使用各种流我们可以指定要干什么什么，而不是怎么干，将具体的实现留给库来做。比如我们要计算一个整数列表的平均值，使用流库的话，我们只需要指定数据源和结果属性。然后流库来进行具体的计算，由于细节是流库实现的，因此它也可以对计算进行优化，以提高效率。

简而言之，有了流库，之前需要写很多行代码实现的操作，现在可能只需一行就能搞定了，而且效率可能会更高。

# 概念引入

以一个简单的例子来引入流。比如我们想统一某个字符串中某个单词出现的频率。

```java
/**
 * 统计某个单词出现次数
 */
public void function1() {
    // 通过非字母分割字符串
    List<String> strs = Arrays.asList("I love you! Do you love me?".split("\\PL+"));
    //传统
    int count = 0;
    for (String str : strs) {
        if (str.equals("you")) {
            count++;
        }
    }

    // 使用流
    long streamCount = strs.stream().filter(item -> item.equals("you")).count();
}
```

流遵循了 **做什么而非怎么做** 的原则，上面的流版本中，我们仅仅描述了要做什么：获取单词"you"出现的次数.

流具有以下三大特性：

- 流并不存储元素。流的元素要么来源底层的集合，要么是即时生成的(通过一个函数生成)
- 流的操作不会修改底层数据源（不会修改源集合）
- 流的操作是尽可能惰性的。只有在需要其结果的时候，操作才会执行。

流分为两大类：

- stream 顺序流
- parallelStream 并行流。会尽量利用多线程来提高速度

# 流的创建

## 从集合创建

很简单，通过 Collection 接口的 stream(parallelStream)方法，可以将任意一个集合转换为流。

```java
//strs为一个集合
Stream stream = strs.stream();
stream = strs.parallelStream();
```

## 从数组创建

