【Java】25 Stream 流
在 JDK 1.8 中,得益于 Lambda 表达式所带来的函数式编程,引入了一个全新的 Stream 概念,用于解决已有集合类库既有的弊端。
1.1 初识 Stream
1.1.1 集合类库弊端
我们需要筛选出集合中元素包含“叁”的元素,但是我们却遍历了元素集合,这无疑是累赘的。
public class Demo {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("壹");
list.add("贰");
list.add("叁");
list.add("肆");
list.add("伍");
List<String> tempList = new ArrayList<>();
for (String name : list) {
if (name.contains("叁")) {
tempList.add(name);
}
}
for (String s : tempList) {
System.out.println(s);
}
}
}
1.1.2 Stream 更优写法
下述代码中并没有体现出遍历操作,我们可以更好地体现做什么而不是怎么做。
public class Demo {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("壹");
list.add("贰");
list.add("叁");
list.add("肆");
list.add("伍");
// :: 方法引用,如果已有方法能够完成函数式接口中的功能,就可以使用方法引用替换 Lambda
list.stream().filter(s -> s.contains("叁")).forEach(System.out::println);
}
}
1.1.3 Stream 概述
Stream 是 JDK 1.8 中处理集合的关键抽象概念,它可以指定你希望对集合进行的操作,可以执行非常复杂的查找、过滤和映射数据等操作。使用 Stream API 对集合数据进行操作,就类似于使用 SQL 执行的数据库查询。也可以使用 Stream API 来并行执行操作。简而言之,Stream API 提供了一种高效且易于使用的处理数据的方式。Stream 有如下特点: ♞ 不是数据结构,不会保存数据。 ♞ 不会修改原来的数据源,它会将操作后的数据保存到另外一个对象中。 ♞ 惰性求值,流在中间处理过程中,只是对操作进行了记录,并不会立即执行,需要等到执行终止操作的时候才会进行实际的计算。 Stream 就像是流水线上生产的产品,直到最后一步才会生成成品。
1.2 获取流
1.2.1 Collection 集合获取流
collection 集合可以通过 stream( ) 默认方法获取流
public class Demo {
public static void main(String[] args) {
Collection<String> collection = new ArrayList<>();
collection.add("壹");
collection.add("贰");
collection.add("叁");
collection.add("肆");
collection.add("伍");
Stream<String> stream = collection.stream();
}
}
1.2.2 数组获取流
数组通过 Stream 接口的静态方法 of( ) 获取流,基本数据类型数组不能使用 Stream.of( )。
public class Demo {
public static void main(String[] args) {
Integer[] array = {1, 2, 3, 4, 5};
Stream<Integer> stream = Stream.of(array);
}
}
1.3 操作符
操作符就是对数据进行的一种处理工作,一道加工程序;就好像工厂的工人对流水线上的产品进行一道加工程序一样。Stream 的操作符分为两种:中间操作符和终止操作符。
1.3.1 中间操作符
操作符 |
说明 |
---|---|
map( ) |
转换操作 |
limit( ) |
限流操作 |
distint( ) |
去重操作 |
filter( ) |
过滤操作 |
peek( ) |
挑出操作 |
skip( ) |
跳过操作 |
sorted( ) |
排序操作 |
concat( ) |
合并操作 |
转换操作
public class Demo {
public static void main(String[] args) {
String[] array = {"1", "2", "3", "4", "5"};
Stream.of(array).map(s -> Integer.parseInt(s))
.forEach(s -> System.out.println(s + "的类型是:" + s.getClass().getName()));
}
}
限流操作
public class Demo {
public static void main(String[] args) {
String[] array = {"1", "2", "3", "4", "5"};
Stream.of(array).limit(3).forEach(System.out::println);
}
}
去重操作
public class Demo {
public static void main(String[] args) {
String[] array = {"1", "2", "3", "1", "1"};
Stream.of(array).distinct().forEach(System.out::println);
}
}
过滤操作
public class Demo {
public static void main(String[] args) {
String[] array = {"1", "2", "3", "1", "1"};
Stream.of(array).filter(s -> !"1".equals(s)).forEach(System.out::println);
}
}
挑出操作
public class Demo {
public static void main(String[] args) {
String[] array = {"1", "2", "3", "4", "5"};
Stream.of(array).skip(3).peek(s -> System.out.println("peek --- " + s)).forEach(System.out::println);
}
}
跳过操作
public class Demo {
public static void main(String[] args) {
String[] array = {"1", "2", "3", "4", "5"};
Stream.of(array).skip(3).forEach(System.out::println);
}
}
排序操作
public class Demo {
public static void main(String[] args) {
String[] array = {"5", "2", "6", "1", "4"};
Stream.of(array).sorted().forEach(System.out::println);
}
}
合并操作
合并操作两个流的数据类型要一致
public class Demo {
public static void main(String[] args) {
String[] array = {"1", "2", "3", "4", "5"};
List<String> list = new ArrayList<>();
list.add("壹");
list.add("贰");
list.add("叁");
list.add("肆");
list.add("伍");
Stream.concat(Stream.of(array), list.stream()).forEach(System.out::println);
}
}
1.3.2 终止操作符
终止操作符就是用来对数据进行收集或者消费的,数据到了终止操作这里就不会向下流动了,终止操作符只能使用一次。
操作符 |
说明 |
---|---|
count |
统计操作 |
forEach |
遍历操作 |
toArray |
数组操作 |
统计操作
public class Demo {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("壹");
list.add("贰");
list.add("叁");
list.add("肆");
list.add("伍");
long count = list.stream().filter(s -> !"叁".equals(s)).count();
System.out.println(count);
}
}
遍历操作
public class Demo {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("壹");
list.add("贰");
list.add("叁");
list.add("肆");
list.add("伍");
list.stream().filter(s -> !"叁".equals(s)).forEach(System.out::println);
}
}
数组操作
public class Demo {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("壹");
list.add("贰");
list.add("叁");
list.add("肆");
list.add("伍");
Object[] objects = list.stream().filter(s -> !"叁".equals(s)).toArray();
System.out.println(Arrays.toString(objects));
}
}
每个 Stream 流只能使用一次 Stream 流必须使用 终止操作符 否则不会有输出
- 根据前后的子串求中间串的函数
- Centos6下zookeeper集群部署记录
- 抓取百度指数引发的图像数字识别
- 真正将标注文字遮盖的方法
- “AS3.0高级动画编程”学习:第四章 寻路(AStar/A星/A*)算法 (中)
- li浮动时ul高度为0,解决ul自适应高度的几种方法
- 使用正则表达式求完整路径中的文件名
- “AS3.0高级动画编程”学习:第四章 寻路(AStar/A星/A*)算法 (下)
- Centos下SFTP双机高可用环境部署记录
- as3:Function以及call,apply
- centos6下redis cluster集群部署过程
- centos6下ActiveMQ+Zookeeper消息中间件集群部署记录
- 发布一个轻量级的滑块控件
- as3:sprite作为容器使用时,最好不要指定width,height
- java教程
- Java快速入门
- Java 开发环境配置
- Java基本语法
- Java 对象和类
- Java 基本数据类型
- Java 变量类型
- Java 修饰符
- Java 运算符
- Java 循环结构
- Java 分支结构
- Java Number类
- Java Character类
- Java String类
- Java StringBuffer和StringBuilder类
- Java 数组
- Java 日期时间
- Java 正则表达式
- Java 方法
- Java 流(Stream)、文件(File)和IO
- Java 异常处理
- Java 继承
- Java 重写(Override)与重载(Overload)
- Java 多态
- Java 抽象类
- Java 封装
- Java 接口
- Java 包(package)
- Java 数据结构
- Java 集合框架
- Java 泛型
- Java 序列化
- Java 网络编程
- Java 发送邮件
- Java 多线程编程
- Java Applet基础
- Java 文档注释