首页 > 编程语言 >java-----Stream流

java-----Stream流

时间:2024-09-18 19:52:28浏览次数:12  
标签:java stream Stream System 张无忌 ----- println out

什么是Stream?

Stream将要处理的元素集合看作一种流,在流的过程中,借助Stream API对流中的元素进行操作,比如:筛选、排序、聚合等

Stream流的作用:

结合了Lambda表达式,简化集合、数组的操作

Stream流的使用步骤:

        ①先得到一条Stream流(流水线),并把数据放上去

        ②利用Stream流中的API进行各种操作:比如

中间方法:(过滤、转换) 方法调用完毕之后,还可以调用其他方法

终结方法:(统计、打印) 最后一步,调用完毕之后,不能调用其它方法

总的来说三步:

        1.先得到一条Stream流(流水线),并把数据放上去

        2.使用中间方法对流水线上的数据进行操作

        3.使用终结方法对流水线上的数据进行操作

让我们来一步步介绍

①得到一条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接口中的静态方法

方法演示:       

package StreamDemo;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.function.Consumer;
import java.util.stream.Stream;

public class demo1 {
    public static void main(String[] args) {
        ArrayList<String> list=new ArrayList<>();
        Collections.addAll(list,"a","b","c","d","e");
        Stream<String> stream = list.stream();//ctrl+v自动生成左边

        list.stream().forEach(s->{
            System.out.println(s);
        });

        //双列集合获取Stream流时必须利用keySet()或者entrySet()方法获取单列集合,然后再获取流
        HashMap<String,Integer> hm=new HashMap<>();
        hm.put("aaa",111);
        hm.put("bbb",222);

        hm.keySet().stream().forEach(s->System.out.println(s));
        hm.entrySet().stream().forEach(s->System.out.println(s.getKey()));

        int []arr={1,2,3,4,5,6};
        Arrays.stream(arr).forEach(s->System.out.println(s));
        
        //Stream接口中静态方法of的细节
        //方法形参是一个可变参数,可以传递一堆零散数据,也可以传递数组
        //但是数组必须是引用数据类型,如果传递基本数据类型,会把整个数组当作一个元素,放入Stream中
        Stream.of(arr).forEach(s->System.out.println(s));

        String []arr2={"a","b","c"};
        Stream.of(arr2).forEach(s->System.out.println(s));
    }
}



运行结果:
aaa
bbb
aaa
bbb
1
2
3
4
5
6
[I@7699a589
a
b
c

②使用中间方法对流水线上的数据进行操作

名称说明
Stream<T>filter(Predicate<?super T>) predicate过滤
Stream<T>limit(long maxSize)获取前几个元素
Stream<T>skip(long n)跳过前几个元素
Stream<T>distinct元素去重
static<T>Stream<T>concat(Stream a,Stream b)合并a和b为一个流
static<R>map(Function<T,R> mapper)转换流中的数据类型

注意1:中间方法,返回新的Stream流,原来的Stream流只能使用一次,建议使用链式编程

注意2:修改Stream流中数据,不会影响原来的集合或者数组中的数据

代码演示:

package StreamDemo;

import java.util.ArrayList;
import java.util.Collections;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Stream;

public class demo3 {
    public static void main(String[] args) {

        ArrayList<String> list=new ArrayList<>();
        Collections.addAll(list,"张无忌","周芷若","赵敏","张强","张三丰","张翠三","张良","王二麻子","谢广坤");

        //1.filter 过滤,把张开头的留下,其余过滤不变
        System.out.print("filter:把张开头的留下");
        Stream<String> stream = list.stream();
        stream.filter(new Predicate<String>() {
            @Override
            public boolean test(String s) {
                //如果为true,则把当前数据的留下
                //如果为false,则把当前数据舍弃
                return s.startsWith("张");
            }
        }).forEach(s->System.out.print(s+" "));
        System.out.println();
        //把姓张且长度为3进行过滤
        //以下的方法会报错 stream has already been operated upon or closed :正好验证了注意1:中间方法,返回新的Stream流,原来的Stream流只能使用一次,建议使用链式编程
        //stream.filter(s->s.length()==3).forEach(s->System.out.println(s));
        //那么我们试试链式编程
        System.out.print("filter链式编程:");
        list.stream().filter(s->s.startsWith("张")).filter(s->s.length()==3).forEach(s->System.out.print(s+" "));
        System.out.println();
        System.out.print("集合里面的数据:");
        System.out.println(list);//注意2:修改Stream流中数据,不会影响原来的集合或者数组中的数据

        //limit 获取前三个元素
        System.out.print("limit 获取前三个元素");
        list.stream().limit(3).forEach(s->System.out.print(s+" "));
        System.out.println();
        System.out.print("skip 跳过前几个元素:");
        list.stream().skip(3).forEach(s->System.out.print(s+" "));
        System.out.println();
        System.out.print("去重之后:");
        ArrayList<String> list2=new ArrayList();
        Collections.addAll(list2,"张无忌","张无忌","张无忌","张无忌","张无忌","张无忌","张无忌","王二麻子","谢广坤");
        //distinct 去重 看源码可以知道distinct底层时hashSet
        list2.stream().distinct().forEach(s->System.out.print(s+" "));

        //concat 合并两个流
        System.out.println("concat 合并两个流:");
        Stream.concat(list.stream(),list2.stream()).forEach(s->System.out.print(s+" "));
        System.out.println();

        //map转换流中的数据类型
        System.out.print("stream.map转换数据类型 获取集合中的年龄:");
        ArrayList<String> list3=new ArrayList<>();
        Collections.addAll(list3,"张无忌-13","周芷若-14","赵敏-15","张强-16","张三丰-15");
        list3.stream().map(new Function<String, Integer>() {//函数式接口
            @Override
            public Integer apply(String s) {
                String []arr=s.split("-");
                int x=Integer.parseInt(arr[1]);
                return x;
            }
        }).forEach(s->System.out.print(s+" "));
        System.out.println();
    }
}

 运行结果:

filter:把张开头的留下张无忌 张强 张三丰 张翠三 张良 
filter链式编程:张无忌 张三丰 张翠三 
集合里面的数据:[张无忌, 周芷若, 赵敏, 张强, 张三丰, 张翠三, 张良, 王二麻子, 谢广坤]
limit 获取前三个元素张无忌 周芷若 赵敏 
skip 跳过前几个元素:张强 张三丰 张翠三 张良 王二麻子 谢广坤 
去重之后:张无忌 王二麻子 谢广坤 concat 合并两个流:
张无忌 周芷若 赵敏 张强 张三丰 张翠三 张良 王二麻子 谢广坤 张无忌 张无忌 张无忌 张无忌 张无忌 张无忌 张无忌 王二麻子 谢广坤 
stream.map转换数据类型 获取集合中的年龄:
13 14 15 16 15 
 

 ③Stream流中的终结方法

名称        说明
void forEach(Consumer action)遍历
long count()统计
toArray()收集流中的数据,放到数组中
collect(Collector collector)收集流中的数据,放到集合中

package StreamDemo;

import java.util.*;
import java.util.function.Function;
import java.util.function.IntFunction;
import java.util.function.Predicate;
import java.util.stream.Collectors;

public class demo4 {
    public static void main(String[] args) {
        System.out.println("forEach获取流中的每一个数据");
        ArrayList<String> list=new ArrayList<>();
        Collections.addAll(list,"张无忌","周芷若","赵敏","张强","张三丰","张翠三","张良","王二麻子","谢广坤");

        list.stream().forEach(s->System.out.print(s+" "));
        System.out.println();
        System.out.println("count统计流中的数据个数:");
        System.out.print(list.stream().count());
        System.out.println();

        System.out.println("收集流中的数据,放到数组里");

        //apply的形参:流中数据的个数
        String []arr=list.stream().toArray(new IntFunction<String[]>() {
            @Override
            public String[] apply(int value) {
                return new String[value];
            }
        });
        System.out.print(Arrays.toString(arr));
        System.out.println();

        ArrayList<String> list3=new ArrayList<>();
        Collections.addAll(list3,"张无忌-13-男","周芷若-14-女","赵敏-15-女","张强-16-男","张三丰-15-男","张三丰-15-男");

        System.out.println("collect方法收集流中的数据并把其放入集合中");
        //获取到所有的男性,并把其放到集合中
        List<String> list4=list3.stream().filter(new Predicate<String>() {
            @Override
            public boolean test(String s) {
                return s.split("-")[2].equals("男");
            }
        }).collect(Collectors.toList());
        System.out.println("收集到list集合中:"+list4);

        //放入Set集合

        Set<String> set=list3.stream().filter(new Predicate<String>() {
            @Override
            public boolean test(String s) {
                return s.split("-")[2].equals("男");
            }
        }).collect(Collectors.toSet());
        System.out.println("收集到set集合中:"+set);

        //收集到map集合中 键姓名 值男性
        /*
         toMap:
            参数一表示键的生成规则
            参数二表示值的生成规则
            参数一:
                Function泛型一:表示流中每一个数据的类型
                        泛型二:表示map集合中键的数据类型
                方法apply形参:依次表示流里面的每一个数据
                            方法体:生成键的代码
                            返回值:已经生成的键
             参数二:
                Function泛型一:表示流中每一个数据的类型
                        泛型二:表示map集合中值的数据类型
                方法apply形参:依次表示流里面的每一个数据
                            方法体:生成值的代码
                            返回值:已经生成的值
      */
        ArrayList<String> list5=new ArrayList<>();
        Collections.addAll(list5,"张无忌-13-男","周芷若-14-女","赵敏-15-女","张强-16-男","张三丰-15-男");
        //注意点
        //键不能重复,不然会报错
        Map<String,String> map=list5.stream().filter(new Predicate<String>() {
            @Override
            public boolean test(String s) {
                return s.split("-")[2].equals("男");
            }
        }).collect(Collectors.toMap(new Function<String, String>() {
            @Override
            public String apply(String s) {
                return s.split("-")[0];
            }
        }, new Function<String, String>() {
            @Override
            public String apply(String s) {
                return s.split("-")[2];
            }
        }));//写键的规则和值的规则
        System.out.println("收集到,map集合中:"+map);
    }



}

 运行结果:

forEach获取流中的每一个数据
张无忌 周芷若 赵敏 张强 张三丰 张翠三 张良 王二麻子 谢广坤 
count统计流中的数据个数:
9
收集流中的数据,放到数组里
[张无忌, 周芷若, 赵敏, 张强, 张三丰, 张翠三, 张良, 王二麻子, 谢广坤]
collect方法收集流中的数据并把其放入集合中
收集到list集合中:[张无忌-13-男, 张强-16-男, 张三丰-15-男, 张三丰-15-男]
收集到set集合中:[张强-16-男, 张三丰-15-男, 张无忌-13-男]
收集到,map集合中:{张强=男, 张三丰=男, 张无忌=男}

内容来自Stream流-02-Stream流的思想和获取Stream流_哔哩哔哩_bilibili

标签:java,stream,Stream,System,张无忌,-----,println,out
From: https://blog.csdn.net/qq_44766305/article/details/142338561

相关文章

  • 基于django+vue个人健康管理APPapp端【开题报告+程序+论文】-计算机毕设
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表开题报告内容研究背景在快节奏的现代生活中,健康已成为人们日益关注的焦点。随着科技的飞速发展,智能手机普及率的大幅提升,以及大数据、人工智能等技术的广泛应用......
  • 基于django+vue个人博客微信小程序演示录像22023【开题报告+程序+论文】-计算机毕设
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表开题报告内容研究背景随着移动互联网的飞速发展,微信小程序作为一种轻量级、无需下载即可使用的应用形态,已经深入人们的日常生活。个人博客作为个人表达、知识分......
  • Springboot化妆品销售5571i--(程序+源码+数据库+调试部署+开发环境)
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表开题报告内容一、项目背景随着消费者生活水平的提高和审美意识的增强,化妆品行业迎来了前所未有的发展机遇。市场上化妆品种类繁多,品牌竞争激烈,消费者对产品的品......
  • 基于django+vue个人博客微信小程序【开题报告+程序+论文】-计算机毕设
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表开题报告内容研究背景随着移动互联网的迅猛发展,微信小程序以其无需下载、即用即走的特点,迅速成为用户获取信息、交流互动的重要平台。个人博客作为个人思想展示......
  • 基于django+vue隔离酒店管理系统【开题报告+程序+论文】-计算机毕设
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表开题报告内容研究背景随着全球公共卫生事件的频发,隔离酒店作为疫情防控的重要一环,其管理效率与服务质量直接关系到疫情防控的效果与公众健康安全。传统的人工管......
  • [Java基础]Stream流
    当我第一次阅读Java8中的StreamAPI时,说实话,我非常困惑,因为它的名字听起来与JavaI0框架中的InputStream和OutputStream非常类似。但是实际上,它们完全是不同的东西。Java8Stream使用的是函数式编程模式,如同它的名字一样,它可以被用来对集合进行链状流式的操作。本文......
  • JDK21中找不到 javax.annotation.Resource 了?
    在JDK9及以后版本,特别是到JDK21,javax.annotation.Resource这样的类已经不再包含在标准的JDK中。原因是从JDK9开始,Java进行了模块化(ProjectJigsaw),并移除了部分与JavaEE(现在称为JakartaEE)相关的包,例如javax.annotation。为什么会找不到javax.annotation.Resourc......
  • Dynamic Locomotion in the MIT Cheetah 3 Through Convex Model-Predictive Control
    1.SwingLegControl\(J_i\inR^{3*3}\)是足端雅可比;\(\tau_{i,ff}\)是前馈力矩\(\Lambda\inR^{3*3}\)是操作空间惯性矩阵;\(a_{i,ref}\inR^{3*3}\)是机体坐标系下的参考加速度q是关节角度;\(C_i\dot{q}_i+G_i\)是科里奥利力和重力2.GroundForceControl\(\tau......
  • General OCR Theory: Towards OCR-2.0 via a Unified End-to-end Model
    摘要传统的OCR系统(OCR-1.0)越来越无法满足人们对智能处理人造光学字符的需求。在本文中,我们将所有人造光学信号(例如,普通文本、数学/分子公式、表格、图表、乐谱,甚至是几何形状)统称为“字符”,并提出了通用OCR理论以及一个优秀的模型,即GOT,以促进OCR-2.0的到来。GOT拥有5.8亿参......
  • 学习高校课程-软件工程-软件工程(ch2)
    2.1DEFININGTHEDISCIPLINEdefinitionforsoftwareengineering软件工程的定义(1)Theapplicationofasystematic,disciplined,quantifiableapproachtothedevelopment,operation,andmaintenanceofsoftware;thatis,theapplicationofengineeringtosoftw......