Loading... > 在C++,C#,java等编程语言中,有一个stream这个类,所有的I/O都以这个“流”类为基础的,包括我们要认识的文件I/O。Java中的Stream(流)是一个来自数据源的元素队列。 # 1、概述 java.util.stream.Stream: Stream(流)是一个来自数据源的元素队列。 * 元素是特定类型的对象,形成一个队列。 Java中的Stream并不会存储元素,而是按需计算。 * 数据源 流的来源。 可以是集合,数组 等。 * Stream流是一个管道流,只能使用一次。 * Pipelining: 中间操作都会返回流对象本身。 这样多个操作可以串联成一个管道, 如同流式风格(fluent style)。 这样做可以对操作进行优化, 比如延迟执行(laziness)和短路( short-circuiting)。 * 内部迭代: 以前对集合遍历都是通过Iterator或者增强for的方式, 显式的在集合外部进行迭代, 这叫做外部迭 代。 Stream提供了内部迭代的方式,流可以直接调用遍历方法。 当使用一个流的时候,通常包括三个基本步骤:获取一个数据源(source)→ 数据转换→执行操作获取想要的结 果,每次转换原有 Stream 对象不改变,返回一个新的 Stream 对象(可以有多次转换),这就允许对其操作可以 像链条一样排列,变成一个管道。 # 2、获取流 java.util.stream.Stream:Java 8新加入的最常用的流接口。(这并不是一个函数式接口。) 获取流的方法: * 所有的 `Collection` 集合都可以通过 `stream()` 方法获取流; * `Stream` 接口的静态方法 `of()` 可以获取数组对应的流。该方法的参数是一个可变参数,所以支持数组。 * `java.util.Map` 接口不是 Collection 的子接口,且其 `K-V` 数据结构不符合流元素的单一特征,所以获取对应的流需要分 `key` 、 `value` 或 `entry` 等情况。 # 3、常用方法 * 延迟方法:返回值类型仍然是 Stream 接口自身类型的方法,因此支持链式调用。(除了终结方法外,其余方 法均为延迟方法。) * 终结方法:返回值类型不再是 Stream 接口自身类型的方法,不支持链式调用。 `count()` 、 `forEach()` `void forEach(Consumer<? super T> action)` :逐一处理、遍历。该方法接收一个 Consumer 接口函数,会将每一个流元素交给该函数进行处理。 `Stream<T> filter(Predicate<? super T> predicate)` :过滤。该方法接收一个 Predicate 函数式接口参数(可以是一个Lambda或方法引用)作为筛选条件。 `<R> Stream<R> map(Function<? super T, ? super R> mapper)` :映射。要将流中的元素映射到另一个流中。该方法需要一个 Function 函数式接口参数,可以将当前流中的T类型数据转换为另一种R类型的流。 `long count()` :统计个数。该方法返回一个long值代表元素个数(不再像旧集合那样是int值)。 `Stream<T> limit(long maxSize)` :截取。参数是一个long型,如果集合当前长度大于参数则进行截取;否则不进行操作。 `Stream<T> skip(long n)` :跳过。如果流的当前长度大于n,则跳过前n个;否则将会得到一个长度为0的空流。 `static <T> Stream<T> concat(Stream<? extends T> a, Stream<? extends T> b)` :组合。将两个流合并为一个流。这是一个静态方法,与 java.lang.String 当中的 concat 方法是不同的。 # 4、集合元素处理练习 现在有两个 ArrayList 集合存储队伍当中的多个成员姓名,依次进行以 下若干操作步骤: 1. 第一个队伍只要名字为3个字的成员姓名;筛选之后只要前3个人; 2. 第二个队伍只要姓张的成员姓名;筛选之后不要前2个人; 3. 将两个队伍合并为一个队伍;根据姓名创建 Person 对象;存储到一个新集合中。 ```java has-numbering public class Person { private String name; public Person() { } public Person(String name) { this.name = name; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "Person{" + "name='" + name + '\'' + '}'; } } ``` ```java has-numbering public static void main(String[] args) { // 第一个队伍 ArrayList<String> one = new ArrayList<>(); one.add("师兄"); one.add("大师姐"); one.add("大师妹"); one.add("师妹1"); one.add("师妹2"); one.add("美女"); // 第二个队伍 ArrayList<String> two = new ArrayList<>(); two.add("小师兄"); two.add("小师姐"); two.add("张美女"); two.add("张大哥"); two.add("张师妹妹"); // 使用Stream流进行操作 Stream<String> streamOne = one.stream().filter(s -> s.length() == 3).limit(3); Stream<String> streamTwo = two.stream().filter(s -> s.startsWith("张")).skip(2); Stream.concat(streamOne, streamTwo).map(Person::new).forEach(System.out::println); } ``` > 感谢小伙伴们的关注! > 你的点赞、评论、关注、收藏是对博主的最大鼓励! > 持续更新JavaSE学习笔记!欢迎订阅专栏! 最后修改:2021 年 10 月 06 日 © 允许规范转载 打赏 赞赏作者 支付宝微信 赞 如果觉得我的文章对你有用,请随意赞赏