Stream流
1. 概述
Stream流是Java 8引入的一种新的数据处理方式,它可以用来处理集合(包括单列集合和双列集合)和数组中的数据。它提供了一种优雅、声明式的方式来对数据进行操作和处理,简化了对集合和数组的遍历、过滤、映射、排序等操作。
Stream流可以被认为是一种高级版本的迭代器。
- 与传统的集合迭代器相比,Stream流具有以下特点:
-
Stream流不会对原有的数据集合进行修改,而是通过生成一个新的Stream流来进行操作。这种特性称为“惰性求值”,也就是说在对Stream流的操作时,并不会立即执行,只有在终止操作(如
forEach
、collect
等)被调用时才会真正执行计算过程。 -
Stream流支持并发操作,可以使用并行流来进行高效的多线程处理。通过并行化操作,可以极大地提高处理大数据集的效率。
-
Stream流的使用步骤:
- 创建Stream流
可以通过集合类的
stream()
方法、数组的stream()
方法,或者使用Stream.of()
方法来创建。- 进行一系列中间操作
通过调用Stream流的方法来对数据进行过滤、映射、排序等操作,这些操作会返回一个新的Stream流。
- 执行终止操作
使用终止操作来触发对Stream流的计算。常见的终止操作包括
forEach
(遍历每个元素执行特定的操作)、collect
(将元素收集到一个结果容器中)、reduce
(归约操作,将多个元素合并为一个结果)等等。 -
代码示例
按照下面的要求完成集合的创建和遍历“张三丰”,“张无忌”,“张翠山”,“王二麻子”,“张良”,“谢广坤”
-
创建一个集合,存储多个字符串元素
-
把集合中所有以"张"开头的元素存储到一个新的集合
-
把"张"开头的集合中的长度为3的元素存储到一个新的集合
-
遍历上一步得到的集合
package text.text02; import java.util.ArrayList; import java.util.Collections; import java.util.function.Consumer; /*初爽Stream流 按照下面的要求完成集合的创建和遍历 "张三丰","张无忌","张翠山","王二麻子","张良","谢广坤" - 创建一个集合,存储多个字符串元素 - 把集合中所有以"张"开头的元素存储到一个新的集合 - 把"张"开头的集合中的长度为3的元素存储到一个新的集合 - 遍历上一步得到的集合 */ public class text62 { public static void main(String[] args) { //未使用Stream流 System.out.println("未使用Stream流:"); method1(); //使用了Stream流 System.out.println("使用了Stream流:"); method2(); } //使用了Stream流 private static void method2() { //创建集合并添加字符串元素 ArrayList<String> list = new ArrayList<>(); Collections.addAll(list, "张三丰", "张无忌", "张翠山", "王二麻子", "张良", "谢广坤"); list.stream() .filter(name -> name.startsWith("张")) .filter(name -> name.length() == 3) .forEach(new Consumer<String>() { @Override public void accept(String name) { System.out.print(name + " "); } }); } //未使用Stream流 public static void method1() { //创建集合并添加字符串元素 ArrayList<String> list = new ArrayList<>(); Collections.addAll(list, "张三丰", "张无忌", "张翠山", "王二麻子", "张良", "谢广坤"); //遍历集合获取以“张”开头的元素,并存在新的集合中 ArrayList<String> list1 = new ArrayList<>(); for (String name : list) { if (name.startsWith("张")) { list1.add(name); } } System.out.println("所有以\"张\"开头的元素存储到一个新的集合:" + list1); //[张三丰, 张无忌, 张翠山, 张良] //把"张"开头的集合中的长度为3的元素存储到一个新的集合 ArrayList<String> list2 = new ArrayList<>(); for (String name : list1) { if (name.length() == 3) { list2.add(name); } } System.out.println("把\"张\"开头的集合中的长度为3的元素存储到一个新的集合:" + list2); //[张三丰, 张无忌, 张翠山] } }
-
-
输出结果
-
未使用Stream流
-
使用了Stream流
-
2. 方法
2.1 开始生成方法
2.1.1 概述
Stream流开始生成方法是指用于创建和获取Stream流的一些方法。在Java中,Stream是一种处理数据集合的抽象概念,它提供了丰富的数据操作和处理功能。
为了使用Stream,我们需要首先生成或获取到一个Stream流对象。
-
生成Stream流的方式
-
Collection体系集合
使用默认方法stream()生成流, default Stream stream()
-
Map体系集合
把Map转成Set集合,间接的生成流
-
数组
通过Arrays中的静态方法stream生成流
-
同种数据类型的多个数据
通过Stream接口的静态方法of(T… values)生成流
-
2.1.2 方法
获取方式 | 方法名 | 说明 |
---|---|---|
单列集合 | default Streamstream() | Collection中的默认方法 |
双列集合 | 无 | 无法直接使用stream流 |
数组 | public static Stream stream(T[] array) | Arrays工具类中的静态方法 |
-堆零散数据 | public staticStream of(T… values) | Stream接口中的静态方法 |
细节:
-
单列集合:
default Stream<E> stream()
,此方法是Collection
接口中的默认方法,用于将单列集合(如List、Set)转换为Stream流。例如:
List<String> list = Arrays.asList("A", "B", "C"); Stream<String> stream = list.stream();
-
双列集合:目前没有直接使用
stream()
方法将双列集合(如Map)转换为Stream流的方式。但是可以通过entrySet().stream()
或keySet().stream()
等方式间接获得Stream流,以对双列集合进行操作。 -
数组:
public static <T> Stream<T> stream(T[] array)
,此方法是Arrays
工具类中的静态方法,用于将数组转换为Stream流。例如:
String[] array = { "A", "B", "C"}; Stream<String> stream = Arrays.stream(array);
-
散零数据:
public static <T> Stream<T> of(T... values)
,此方法是Stream
接口中的静态方法,用于将一系列散零的数据转换为Stream流。例如:
Stream<String> stream = Stream.of("A", "B", "C");
2.1.3 代码示例
-
代码示例1:单列集合
package text.text02; import java.util.ArrayList; import java.util.Collections; import java.util.function.Consumer; import java.util.stream.Stream; /*生成方法: 单列集合 | default Stream<E>stream() | 获取方式 | 方法名 | 说明 | | ----------- | --------------------------------------------- | ------------------------ | | 单列集合 | default Stream<E>stream() | Collection中的默认方法 | | 双列集合 | 无 | 无法直接使用stream流 | | 数组 | public static <T> Stream<T> stream(T[] array) | Arrays工具类中的静态方法 | | -堆零散数据 | public static<T>Stream<T> of(T... values) | Stream接口中的静态方法 | */ public class text63 { public static void main(String[] args) { //完整模式 System.out.println("完整模式:"); method1(); //aaa bbb ccc ddd eee fff ggg hhh iii jjj kkk System.out.println(); //简写模式 System.out.println("简写模式:"); method2(); //aaa bbb ccc ddd eee fff ggg hhh iii jjj kkk } //简写模式 private static void method2() { //创建单列集合 ArrayList<String> list = new ArrayList<>(); //添加数据 Collections.addAll(list, "aaa", "bbb", "ccc", "ddd", "eee", "fff", "ggg", "hhh", "iii", "jjj", "kkk"); //创建Stream流并输出 list.stream() .forEach(s -> System.out.print(s + " ")); } public static void method1() { //创建单列集合 ArrayList<String> list = new ArrayList<>(); //添加数据 Collections.addAll(list, "aaa", "bbb", "ccc", "ddd", "eee", "fff", "ggg", "hhh", "iii", "jjj", "kkk"); //创建Stream流 Stream<String> stream = list.stream(); //输出数据 stream.forEach(new Consumer<String>() { @Override public void accept(String s) { System.out.print(s + " "); } }); } }
-
输出结果:单列集合
-
代码示例2:双列集合
package text.text02; import java.util.HashMap; import java.util.Map; import java.util.Set; import java.util.function.Consumer; /*生成方法: 双列集合 | 无 双列集合无stream流,必须先利用keySet()或者entrySet()方法转化成单列集合才可以使用 | 获取方式 | 方法名 | 说明 | | ----------- | --------------------------------------------- | ------------------------ | | 单列集合 | default Stream<E>stream() | Collection中的默认方法 | | 双列集合 | 无 | 无法直接使用stream流 | | 数组 | public static <T> Stream<T> stream(T[] array) | Arrays工具类中的静态方法 | | -堆零散数据 | public static<T>Stream<T> of(T... values) | Stream接口中的静态方法 | */ public class text64 { public static void main(String[] args) { //创建双列集合 HashMap<String, Integer> hm = new HashMap<>(); //添加数据 hm.put("手机", 1003); hm.put("电脑", 1005); hm.put("平板", 1001); hm.put("汽车", 1002); hm.put("飞机", 1004); //利用keySet()转化成单列集合 System.out.println("===============利用keySet()转化成单列集合==============="); method1(hm); //利用entrySet()方法转化成单列集合 System.out.println("===============利用entrySet()方法转化成单列集合==============="); method2(hm); } //利用entrySet()方法转化成单列集合 private static void method2(HashMap<String, Integer