JAVA进阶 —— Stream流
目录
一、 引言
二、 Stream流概述
三、Stream流的使用步骤
1. 获取Stream流
1.1 单列集合
1.2 双列集合
1.3 数组
1.4 零散数据
2. Stream流的中间方法
3. Stream流的终结方法
四、 练习
1. 数据过滤
2. 数据操作 - 按年龄筛选
3. 数据操作 - 演员信息要求筛选
一、 引言
初识Stream流的作用:
需求:按照下面的要求完成集合的创建和遍历,创建一个集合,存储多个字符串元素
通过下面代码,显然我们清晰的看到使用Stream流更为方便,而使用普通的集合遍历就有些复杂。
public class Test01 {public static void main(String[] args) {ArrayList<String> list1 = new ArrayList<>();list1.add("张无忌");list1.add("周正若");list1.add("赵斌");list1.add("张强");list1.add("张三丰");// Stream流list1.stream().filter(name -> name.startsWith("张")).filter(name -> name.length() == 3).forEach(name -> System.out.println(name));// 张无忌// 张三丰// 1.把所有“张”姓开头元素存储到新集合ArrayList<String> list2 = new ArrayList<>();for (String name : list1) {if (name.startsWith("张")) {list2.add(name);}}System.out.println(list2); // [张无忌, 张强, 张三丰]// 2.把所有“张”姓开头且长度为3的元素存储到新集合ArrayList<String> list3 = new ArrayList<>();for (String name : list2) {if (name.length() == 3) {list3.add(name);}}System.out.println(list3); // [张无忌, 张三丰]}
}
二、 Stream流概述
例如上面的小例子,Stream流的思想如下:
![]() | ![]() | ![]() | ![]() |
顺序筛选 | ![]() |
Stream流的作用就是:
结合了Lambda表达式,简化集合、数字的操作。
三、Stream流的使用步骤
- 先得到一条Stream流(流水线),并把数据放上去。
- 使用中间方法对流水线上的数据进行操作。
- 使用终结方法对流水线上的数据进行操作。
过滤、转换 中间方法 方法调用完毕之后,还可以调用其他方法 统计、打印 终结方法 最后一步,调用完毕之后,不能调用其他方法
1. 获取Stream流
获取方式 | 方法名 | 说明 |
单列集合 | default Stream<E> stream() | Collection中的默认方法 |
双列集合 | 无 | 无法直接使用stream流,需要通过keySet()或者entrySet()变成单列集合 |
数组 | public static <T> Stream <T> stream(T [ ] array) | Arrays工具类中的静态方法 |
一堆零散数据 | public static <T> Stream <T> of(T... values) | stream接口中的静态方法 |
1.1 单列集合
public class StreamTest {public static void main(String[] args) {//单列集合获取Stream流ArrayList<String> list = new ArrayList<>();Collections.addAll(list, "a","b","c","d","e");//获取到一个流水线,并把集合中的数据方法流水线上//Stream<String> stream1 = list.stream();//使用终结方法打印流水线上数据//stream1.forEach( s ->System.out.println(s) );list.stream().forEach(s -> System.out.println(s));}
}
1.2 双列集合
public class StreamTest {public static void main(String[] args) {//双列集合获取Stream流 //1. 创建双列集合HashMap<String, Integer> hm = new HashMap<>();//2. 添加数据hm.put("aaa", 111);hm.put("bbb", 222);hm.put("ccc", 333);//3.1 获取Stream流方法一: keySet()//键hm.keySet().stream().forEach(s -> System.out.println(s));//3.2 获取Stream流方法二:entrySet()//键值对hm.entrySet().stream().forEach(s -> System.out.println(s)); }
}
1.3 数组
Stream接口中静态方法of的细节:
- 方法的形参是一个可变参数,可以传递一堆零散数据,也可以传递数组。
- 但是数组必须是引用数据类型。
- 如果传递的是基本数据类型,是会把整个数组相当做一个元素,放到一个stream流当中。
public class StreamTest {public static void main(String[] args) {//数组获取Stream流 //1.创建基本数据类型数组int[] arr1 = {1,2,3,4,5,6,7,8,9,10};//获取streamArrays.stream(arr1).forEach(s -> System.out.println(s));//2.创建引用数据类型数组String[] arr2 = {"a","b","c"};//获取streamArrays.stream(arr2).forEach(s -> System.out.println(s));//方式是错误的!!!//Stream接口中静态方法of的细节//方法的形参是一个可变参数,可以传递一堆零散数据,也可以传递数组//但是数组必须是引用数据类型//如果传递的是基本数据类型,是会把整个数组相当做一个元素,放到一个stream流当中Stream.of(arr2).forEach(s -> System.out.println(s));Stream.of(arr1).forEach(s -> System.out.println(s)); //[I@1b28cdfa}
}
1.4 零散数据
细节: 一堆零散数据需要是相同的数据类型。
public class StreamTest {public static void main(String[] args) {//零散数据获取Stream流 //基本数据类型Stream.of(1,2,3,4,5).forEach(s -> System.out.println(s));//引用数据类型Stream.of("a","b","c","d","e").forEach(s -> System.out.println(s));}
}
2. Stream流的中间方法
方法名称 | 说明 |
Stream<T> filter ( Predicate<? super T> predicate ) | 过滤 |
Stream<T> limit ( long maxSize) | 获取前几个元素 |
Stream<T> skip ( long n ) | 跳过前几个元素 |
Stream<T> distinct ( ) | 元素去重,依赖(hashCode和equals方法) |
static <T> Stream<T> concat ( Stream a , Stream b ) | 合并a和b两个流为一个流 |
Stream<R> map ( Function<T ,R> mapper ) | 转换流中的数据类型 |
注意一:中间方法,返回新的Stream流,原来的Stream流只能使用一次,建议使用链式编程。
注意二:修改Stream流中的数据,不会影响原来集合或者数组中的数据。
public class StreamTest01 {public static void main(String[] args) {//1.过滤:把开头的留下,其余数据过滤不要ArrayList<String> list = new ArrayList<>();Collections.addAll(list, "张三","李四","王五","赵六","张七");ArrayList<String> list2 = new ArrayList<>();Collections.addAll(list2, "张三","李四","王五","赵六","张三");ArrayList<String> list3 = new ArrayList<>();Collections.addAll(list3, "孙七","钱八");ArrayList<String> list4 = new ArrayList<>();Collections.addAll(list2, "张三-23","李四-24","王五-25");list.stream().filter(new Predicate<String>() {//匿名内部类太麻烦 需要缩写@Overridepublic boolean test(String s) {//如果返回值为true,表示当前数据留下//如果返回值为false,表示当前数据舍弃return s.startsWith("张");}}).forEach(s -> System.out.println(s)); //张三 张七list.stream().filter(s -> s.startsWith("张")).forEach(s -> System.out.println(s));//2. 获取前几个元素 list.stream().limit(3).forEach(s -> System.out.println(s)); //张三 李四 王五//3. 跳过list.stream().skip(4).forEach(s -> System.out.println(s)); //张七//4.去重list2.stream().distinct().forEach(s -> System.out.println(s)); //张三 李四 王五 赵六//5. 合并Stream.concat(list2.stream(), list3.stream()).forEach(s -> System.out.println(s));//6.转换数据类型//只能获取集合里面的年龄并打印//第一个类型:流中原本的数据类型//第二个类型:将要转变成为的数据类型list4.stream().map(new Function<String,Integer>() {@Override//apply: 依次表示流中的每一盒数据//返回值:表示转化之前的数据public Integer apply(String s) {String[] arr = s.split("-");String ageString = arr[1];int age = Integer.parseInt(ageString);return age;}}).forEach(s -> System.out.println(s));list.stream().map(s ->Integer.parseInt(s.split("-")[1])).forEach(s -> System.out.println(s));}
}
3. Stream流的终结方法
方法名称 | 说明 |
void forEach ( Consumer action ) | 遍历 |
long count ( ) | 统计 |
toArray ( ) | 收集流中的数据,放到数组中 |
collect ( Collector collector ) | 收集流中的数据,放到集合中 |
public class StreamTest02 {public static void main(String[] args) {ArrayList<String> list = new ArrayList<>();Collections.addAll(list, "张三", "李四", "王五", "赵六");// 遍历// Consumer的泛型:表示流中的数据类型// accept方法的形参s:依次表示流中的每一个数据//list.stream().forEach(new Consumer<String>() {@Overridepublic void accept(String s) {System.out.println(s);}});list.stream().forEach(s -> System.out.println(s)); // 张三 李四 王五 赵六// 统计long count = list.stream().count();System.out.println(count); // 4// 收集数据放进数组Object[] arr1 = list.stream().toArray();System.out.println(Arrays.toString(arr1)); // [张三, 李四, 王五, 赵六]// 指定数据类型// Infunction的泛型:具体类型的数组// apply中形参:流中数据的个数,要跟数组长度一致// apply的返回值:具体类型的数组String[] arr2 = list.stream().toArray(new IntFunction<String[]>() {@Overridepublic String[] apply(int value) {return new String[value];}});// toArray方法中的参数:只是创建一个指定类型的数组// toArray底层: 会此意得到流中的每一个数据,并把数据放到数组中// toArray的返回值:是一个装着流里面所有数据的数组System.out.println(Arrays.toString(arr2));// lambda表达式String[] arr3 = list.stream().toArray(value -> new String[value]);System.out.println(Arrays.toString(arr3));}
}
collect方法:
public class StreamTest {public static void main(String[] args) {ArrayList<String> list = new ArrayList<>();Collections.addAll(list, "张三-男-23", "李四-男-24", "王五-男-25", "赵六-女-27", "孙八-女-28");//收集到List集合当中//需求://将所有的男性收集起来List<String> newList = list.stream().filter(s-> "男".equals(s.split("-")[1])).collect(Collectors.toList());System.out.println(newList); //[张三-男-23, 李四-男-24, 王五-男-25]//收集到Set集合当中Set<String> newSet = list.stream().filter(s-> "男".equals(s.split("-")[1])).collect(Collectors.toSet());System.out.println(newSet);//收集到Map集合当中//键: 姓名 值: 年龄//toMap://参数一表示键的生成规则 参数二表示值得生成规则//参数一: //Function泛型一:表示流中每一个数据的类型 ;// 泛型二:表示Map集合中键的数据类型//方法apply 形参:一次表示流里面的每一个数据// 方法体:生成键的代码 // 返回值:已生成的键//参数二://Function泛型一:表示流中每一个数据的类型 ;// 泛型二:表示Map集合中值的数据类型//方法apply 形参:一次表示流里面的每一个数据// 方法体:生成值的代码 // 返回值:已生成的值Map<String, Integer> newMap = list.stream().filter(s-> "男".equals(s.split("-")[1])).collect(Collectors.toMap(new Function<String, String>() {@Overridepublic String apply(String s) {return s.split("-")[0];}}, new Function<String, Integer >() {@Overridepublic Integer apply(String s) {return Integer.parseInt(s.split("-")[2]);}}));System.out.println(newMap); //{李四=24, 张三=23, 王五=25}//lambda表达式Map<String, Integer> newMap1 = list.stream().filter(s-> "男".equals(s.split("-")[1])).collect(Collectors.toMap( s-> s.split("-")[0], s-> Integer.parseInt(s.split("-")[2])));System.out.println(newMap1);}
}
四、 练习
1. 数据过滤
需求:
定义一个集合,并添加一些整数1,2,3,4,5,6,7,8,9,10
过滤奇数,只留下偶数。
并将结果保存起来
public class StreamDemo {public static void main(String[] args) {// 1.定义一个集合ArrayList<Integer> list = new ArrayList<>();// 2.添加数据Collections.addAll(list, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10);// 3.过滤奇数,只留偶数// 进行判断,如果是偶数,返回trueList<Integer> list2 = list.stream().filter(n -> n % 2 == 0).collect(Collectors.toList());System.out.println(list2); //[2, 4, 6, 8, 10]}
}
2. 数据操作 - 按年龄筛选
需求:
创建一个ArrayList集合,并添加以下字符串,字符串中前面是姓名,后面是年龄“zhangsan,23”
“lisi,24"
“wangwu,25”
保留年龄大于等于24岁的人,并将结果收集到Map集合中,姓名为键,年龄为值
public class StreamDemo {public static void main(String[] args) {// 1.定义一个集合ArrayList<String> list = new ArrayList<>();//2.集合添加字符串list.add( "zhangsan,23");list.add("lisi,24");list.add("wangwu,25");//3.保留年龄大于24岁的人Map<String, Integer> map = list.stream().filter(s -> Integer.parseInt(s.split(",")[1]) >= 24).collect(Collectors.toMap(s -> s.split(",")[0], s -> Integer.parseInt(s.split(",")[1])));System.out.println(map); //{lisi=24, wangwu=25}}
}
3. 数据操作 - 演员信息要求筛选
现在有两个ArrayList集合,
第一个集合中:存储6名男演员的名字和年龄。第二个集合中:存储6名女演员的名字和年龄。姓名和年龄中间用逗号隔开。比如:张三,23
要求完成如下的操作:
- 男演员只要名字为3个字的前两人
- 女演员只要姓杨的,并且不要第一个
- 把过滤后的男演员姓名和女演员姓名合并到一起
- 将上一步的演员信息封装成Actor对象。
- 将所有的演员对象都保存到List集合中。
备注:演员类Actor,属性有:name,age
public class StreamDemo {public static void main(String[] args) {// 1.定义两个集合ArrayList<String> manList = new ArrayList<>();ArrayList<String> womenList = new ArrayList<>();// 2.添加数据Collections.addAll(manList, "蔡坤坤,24", "叶购成,23", "刘不甜,22", "吴签,24", "谷嘉,30", "肖梁梁,27");Collections.addAll(womenList, "赵小颖,35", "杨颖,36", "高元元,43", "张天天,31", "刘诗,35", "杨小幂,33");// 3. 男演员只要名字为3个字的前两个人Stream<String> stream1 = manList.stream().filter(s -> s.split(",")[0].length() == 3).limit(2);
// .forEach(s -> System.out.println(s)); // 蔡坤坤,24 叶购成,23// 叶购成,23//4.女演员只要姓杨的 并且不要第一个Stream<String> stream2 = womenList.stream().filter(s -> s.split(",")[0].startsWith("杨")).skip(1);
// .forEach(s -> System.out.println(s)); //杨小幂,33//5.把过滤的男演员和女演员信息合并在一起//演员信息封装进Actor对象//String -> Actor对象(类型转换)List<Actor> list = Stream.concat(stream1, stream2).map(s -> new Actor(s.split(",")[0],Integer.parseInt(s.split(",")[1]))).collect(Collectors.toList());System.out.println(list);}
}
相关文章:

JAVA进阶 —— Stream流
目录 一、 引言 二、 Stream流概述 三、Stream流的使用步骤 1. 获取Stream流 1.1 单列集合 1.2 双列集合 1.3 数组 1.4 零散数据 2. Stream流的中间方法 3. Stream流的终结方法 四、 练习 1. 数据过滤 2. 数据操作 - 按年龄筛选 3. 数据操作 - 演员信息要求…...

Linux基础命令大全(上)
♥️作者:小刘在C站 ♥️个人主页:小刘主页 ♥️每天分享云计算网络运维课堂笔记,努力不一定有收获,但一定会有收获加油!一起努力,共赴美好人生! ♥️夕阳下,是最美的绽放࿰…...

嵌入式 串口通信
目录 1、通信的基本概念 1.1 串行通信 1.2 并行通信 2、串行通信的特点 2.1 单工 2.2 半双工 2.3 全双工 3、串口在STM32的引脚 4、STM32的串口的接线 4.1 STM32的串口1和电脑通信的接线方式 4.2 单片机和具备串口的设备连接图 5、串口通信协议 6、串口通信…...

C语言函数调用栈
栈溢出(stack overflow)是最常见的二进制漏洞,在介绍栈溢出之前,我们首先需要了解函数调用栈。 函数调用栈是一块连续的用来保存函数运行状态的内存区域,调用函数(caller)和被调用函数…...

【高阶数据结构】红黑树
文章目录1. 使用场景2. 性质3. 结点定义4. 结点旋转5. 结点插入1. 使用场景 Linux进程调度CFSNginx Timer事件管理Epoll事件块的管理 2. 性质 每一个节点是红色或者黑色根节点一定是黑色每个叶子节点是黑色如果一个节点是红色,那么它的两个儿子节点都是黑色从任意…...

网络协议分析期末复习(二)
目录 12. 端口的定义及常见应用对应的端口号 13. UDP协议概述 14.UDP数据报格式及各字段意义 15. UDP-Lite协议概述 16. TCP数据报格式及各字段意义 17. TCP连接建立及协商参数的过程 18. TCP连接释放过程 19. 路由协议分类及各类的具体协议 20. 路由算法常用的度量 2…...

【C++】STL简介 及 string的使用
文章目录1. STL简介1.1 什么是STL1.2 STL的版本1.3 STL的六大组件2. string类的使用2.1 C语言中的字符串2.2 标准库中的string类2.3 string类的常用接口说明1. string类对象的常见构造2. string类对象的容量操作3. string类对象的修改操作4. resize和reserve5. 认识迭代器&…...

MySQL事务详解
🏆今日学习目标: 🍀Spring事务和MySQL事务详解 ✅创作者:林在闪闪发光 ⏰预计时间:30分钟 🎉个人主页:林在闪闪发光的个人主页 🍁林在闪闪发光的个人社区,欢迎你的加入: …...

ChatGPT背后的技术和多模态异构数据处理的未来展望——我与一位资深工程师的走心探讨
上周,我和一位从业三十余年的工程师聊到ChatGPT。 作为一名人工智能领域研究者,我也一直对对话式大型语言模型非常感兴趣,在讨论中,我向他解释这个技术时,他瞬间被其中惊人之处所吸引🙌,我们深…...

iOS-砸壳篇(两种砸壳方式)
CrackerXI砸壳呢,当时你要是使用 frida-ios-dump 也是可以的; https://github.com/AloneMonkey/frida-ios-dump frida-ios-dump: 代码中需要更改的:手机中的内网ip 密码 等 最后放到我的砸壳路径里: python dump.py -l查看应用…...

linux 基础
1.Shell 命令的格式如下:command -options [argument]command: Shell 命令名称。options: 选项,同一种命令可能有不同的选项,不同的选项其实现的功能不同。argument: Shell 命令是可以带参数的,也可以不带参…...
Java:SpringBoot给Controller添加统一路由前缀
网上的文章五花八门,不写SpringBoot的版本号,导致代码拿来主义不好使了。 本文采用的版本 SpringBoot 2.7.7 Java 1.8目录1、默认访问路径2、整个项目增加路由前缀3、通过注解方式增加路由前缀4、按照目录结构添加前缀参考文章1、默认访问路径 packag…...

Java 基于 JAVE 库 实现 视频转音频的批量转换
文章目录 Java 基于 JAVE 库 实现 视频转音频的批量转换Maven:方案一:代码优化:方案二:示例代码:代码优化:结语Java 基于 JAVE 库 实现 视频转音频的批量转换 实现视频转音频的功能需要使用到一个第三方的 Java 库,叫做 JAVE。JAVE 是一个开源的 Java 库,提供了视频和音频转换…...

Spring容器——基于XML注入
1. 容器:IOC IoC 是 Inversion of Control 的简写,译为“控制反转”,它不是一门技术,而是一种设计思想,是一个重要的面向对象编程法则,能够指导我们如何设计出松耦合、更优良的程序 Spring 通过 IoC 容器来…...

设计模式(二十一)----行为型模式之状态模式
1 概述 【例】通过按钮来控制一个电梯的状态,一个电梯有开门状态,关门状态,停止状态,运行状态。每一种状态改变,都有可能要根据其他状态来更新处理。例如,如果电梯门现在处于运行时状态,就不能…...
一分钟理解 AP(Affinity Propagation) 亲和⼒传播算法
从来没有一个算法让我研究好几天都搞不明白,AP算法算是第一个。弄了好几天,打草纸用了几十页,反复琢磨,最后都怀疑人生了。我觉得网上那么多介绍 AP 的文章,基本上没有一篇能讲明白的。最后我都觉得 AP 的作者可能都没…...
使用mybatis的映射文件操作存储过程
先随便创建一个存储过程 DELIMITER $$ CREATE PROCEDURE getUserNameById (IN i_id BIGINT, OUT o_name VARCHAR(10)) BEGINSELECT u.name INTO o_name FROM tb_user u WHERE id i_id; END $$delimiter $$ : 是将sql语句的结束符号先替换成$$的意思,因为sql是遇到…...

世界上最完美的两个软件,太厉害了!
今天给大家介绍两个软件,一个体现了人类在软件开发流程上的极致,另外一个则体现了程序员个体能力的巅峰。01航天飞机飞控软件先来说第一个,航天飞机飞行控制软件,就是下图这个大家伙。航天飞机重达120吨,还携带着2000吨…...

教你成为比卡卡西还牛逼的全能忍者,全拷贝与分割函数
如何成为一个集雷切,写轮眼侦查和拷贝与一身的卡卡西,下面教你! 目录 第一式——雷切! strtok 第二式——写轮眼侦查! strerror函数 第三式——写轮眼拷贝! memcpy 模拟实现memcpy函数 😎…...

【LeetCode】剑指 Offer(24)
目录 题目:剑指 Offer 47. 礼物的最大价值 - 力扣(Leetcode) 题目的接口: 解题思路: 代码: 过啦!!! 写在最后: 题目:剑指 Offer 47. 礼物的…...

iOS 26 携众系统重磅更新,但“苹果智能”仍与国行无缘
美国西海岸的夏天,再次被苹果点燃。一年一度的全球开发者大会 WWDC25 如期而至,这不仅是开发者的盛宴,更是全球数亿苹果用户翘首以盼的科技春晚。今年,苹果依旧为我们带来了全家桶式的系统更新,包括 iOS 26、iPadOS 26…...

springboot 百货中心供应链管理系统小程序
一、前言 随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱,百货中心供应链管理系统被用户普遍使用,为方…...

3.3.1_1 检错编码(奇偶校验码)
从这节课开始,我们会探讨数据链路层的差错控制功能,差错控制功能的主要目标是要发现并且解决一个帧内部的位错误,我们需要使用特殊的编码技术去发现帧内部的位错误,当我们发现位错误之后,通常来说有两种解决方案。第一…...

CMake基础:构建流程详解
目录 1.CMake构建过程的基本流程 2.CMake构建的具体步骤 2.1.创建构建目录 2.2.使用 CMake 生成构建文件 2.3.编译和构建 2.4.清理构建文件 2.5.重新配置和构建 3.跨平台构建示例 4.工具链与交叉编译 5.CMake构建后的项目结构解析 5.1.CMake构建后的目录结构 5.2.构…...
解决本地部署 SmolVLM2 大语言模型运行 flash-attn 报错
出现的问题 安装 flash-attn 会一直卡在 build 那一步或者运行报错 解决办法 是因为你安装的 flash-attn 版本没有对应上,所以报错,到 https://github.com/Dao-AILab/flash-attention/releases 下载对应版本,cu、torch、cp 的版本一定要对…...

(转)什么是DockerCompose?它有什么作用?
一、什么是DockerCompose? DockerCompose可以基于Compose文件帮我们快速的部署分布式应用,而无需手动一个个创建和运行容器。 Compose文件是一个文本文件,通过指令定义集群中的每个容器如何运行。 DockerCompose就是把DockerFile转换成指令去运行。 …...
Java 二维码
Java 二维码 **技术:**谷歌 ZXing 实现 首先添加依赖 <!-- 二维码依赖 --><dependency><groupId>com.google.zxing</groupId><artifactId>core</artifactId><version>3.5.1</version></dependency><de…...

安宝特方案丨船舶智造的“AR+AI+作业标准化管理解决方案”(装配)
船舶制造装配管理现状:装配工作依赖人工经验,装配工人凭借长期实践积累的操作技巧完成零部件组装。企业通常制定了装配作业指导书,但在实际执行中,工人对指导书的理解和遵循程度参差不齐。 船舶装配过程中的挑战与需求 挑战 (1…...

排序算法总结(C++)
目录 一、稳定性二、排序算法选择、冒泡、插入排序归并排序随机快速排序堆排序基数排序计数排序 三、总结 一、稳定性 排序算法的稳定性是指:同样大小的样本 **(同样大小的数据)**在排序之后不会改变原始的相对次序。 稳定性对基础类型对象…...
虚拟电厂发展三大趋势:市场化、技术主导、车网互联
市场化:从政策驱动到多元盈利 政策全面赋能 2025年4月,国家发改委、能源局发布《关于加快推进虚拟电厂发展的指导意见》,首次明确虚拟电厂为“独立市场主体”,提出硬性目标:2027年全国调节能力≥2000万千瓦࿰…...