Stream流
JDK 1.8引入的新特性。用于解决已有集合类库既有的一些弊端。依赖于Lambda 表达式
传统从集合中获取需要的元素
代码如下:
public class Demo01Stream {
public static void main(String[] args) {
// 构建一个集合
List<String> list = new ArrayList<String>();
list.add("abc123");
list.add("aaa22");
list.add("bcd125");
list.add("abcd120");
list.add("bbb230");
// 需要字符串中包含数字1的元素取出来
List<String> list2 = new ArrayList<String>();// abc123 bcd125 abcd120
for (String str: list) {
if (str.contains("1")) {
list2.add(str);
}
}
// 需要集合当中字符串长度不能超过6个的元素取出来
List<String> list3 = new ArrayList<String>();
for (String str: list2) {
if( str.length() <= 6) {
list3.add(str);
}
}
// 遍历查看最终想要的元素集合
for(String str: list3) {
System.out.println(str);
}
}
}
经过观察需要对源集合中的元素进行不断的循环,而且每次循环都需要从头到尾进行遍历
如果希望对集合中的元素进行筛选过滤:
-
将集合A中根据条件一过滤拿到子集合B;
-
再将子集合B根据条件二过滤筛选为子集合C。
Stream流的更优写法
借助于Stream流对象中的API方法:
public class TestStream {
public static void main(String[] args) {
// 构建一个集合 of("abc123","aaa22")
List<String> list = new ArrayList<String>();
list.add("abc123");
list.add("aaa22");
list.add("bcd125");
list.add("abcd120");
list.add("bbb230");
// 需要字符串中包含数字1的元素取出来
Stream<String> stream = list.stream();// 源集合A
// Stream<T> filter(Predicate<? super T> predicate) 返回由与此给定谓词匹配的此流的元素组成的流。 借助于它的方法 booolean test(T t)
Stream<String> stream02 = stream.filter(str -> str.contains("1")); //子集合B
// 需要集合当中字符串长度不能超过6个的元素取出来
Stream<String> stream03 = stream02.filter(str -> str.length() <= 6); // 子集合C
// void forEach(Consumer<? super T> action)对此流的每个元素执行操作。
// 借助于Consumer中的accept(T t) 打印输出
stream03.forEach(str -> System.out.println(str));// 遍历子集合C 打印输出集合中的每个元素
// 再次优化
list.stream().filer(str -> str.contains("1")).filter(str -> str.length() <= 6).forEach(str -> System.out.println(str));
}
}
流式思想概述
整体来看,流式思想类似于工厂中的“生产流水线”。
当需要对多个元素进行操作的时候,尤其是多步操作,考虑到性能以及便利性。首先需要考虑一个"模型"步骤方案。然后按照你设计的步骤方案去执行。
比如你多某中类型的商品进行操作,你需要进行过滤、映射、跳过,计数等操作,这也是我们对集合中的元素操作的步骤,这一套步骤我们称之为一种处理方案,而方案就是一种"函数模型"。
方案中的操作的每一个步骤,我们称之为一个"流",调用指定的api方法,从一个流中转换为另一个流。
都有对应的api方法,filter、map、skip、count都是对函数模型进行操作。
当我们使用一个流的时候,通常需要包含三个基本步骤:①获取一个数据源—>②数据转换---->③执行操作获取想要的结果。每次转换原有的Stream对象,返回一个新的Stream对象。这样我们就可以像链条一样进行操作。
Stream流和以往的Collection集合有所不同。Stream操作有两个基础的特征:
- 中间操作都会返回流对象本身,这样多个操作可以串联成一个管道,如同流式风格,对中间操作进行优化,比如可以进行延迟执行和短路。
- 内部迭代:以前咱们队集合遍历都是迭代器Iterator或者增强for循环,显式的在集合外部进行迭代。这叫做外部迭代。Stream流提供了内部迭代的方法,这个流可以直接调用遍历的方法。
Stream流 其实是一个集合元素的函数模型,他并不是集合,也不是数据结构。其本身并不存储任何元素(地址值)。
Stream流 是一个来自数据源的元素队列:
- 元素是特定类型的对象,形成一个队列。Java当中的Stream并不会存储元素,而是按需计算。
- 数据源 流的来源。可以是集合,也可以是数组等容器。
获取流对象
java.util.stream.Stream<T>
是JDK 1.8引入的新特性,较为常用的接口(本身并不是函数式接口)
获取一个流对象,有以下常见的操作:
- 所有的Collection集合都可以通过stream()默认方法来获取。
- Stream接口里面含有一个静态方法of也可以获取对应的流对象。
根据Collection集合或者of方法获取流对象
只要是Collection集合的实现类或者子接口都可以调用stream默认方法获取流对象
代码如下:
public static void main(String[] args) {
// 把集合转换为Stream流
List<String> list = new ArrayList<>();
Stream<String> stream1 = list.stream();
HashSet<Integer> set = new HashSet<>();
Stream<Integer> stream2 = set.stream()<