一篇文章速通Java开发Stream流(流水线开发附斗地主小游戏综合案例)

1-认识Sream流

是JDK8开始新增的一套API(java.util.stream.*),可以用于操作集合或者数组的数据。

优势:Stream流大量的结合了Lambda语法风格来编程,功能强大,性能高效,代码简洁,可读性好

1.1-体验Stream流

需求:

把集合中所有以“张”开头,且是三个字的元素存储到一个新集合。

1.1.1-传统方案

找出姓张的人,名字为3个字,存储到新集合中去,强调这个遍历的过程。

//目标:认识Sream流,掌握其基本使用步骤,体会其优势特点。
        List<String> list = new ArrayList<>();
        list.add("周芷若");
        list.add("张无忌");
        list.add("赵敏");
        list.add("张三丰");
        list.add("张强");
        list.add("张翠山");


        //1.先用传统方案找出姓张的人,名字为3个字,存储到新集合中去
        List<String> list2 = new ArrayList<>();
        for (String name : list) {
            if (name.startsWith("张") && name.length() == 3) { //StarWith以姓张开始,并且长度为3
                list2.add(name);
            }
        }
        System.out.println(list2);

1.1.2-使用Stream方案

把流理解为一个传送带,把集合里的所有数据扔到这个传送带上

List<String> list = new ArrayList<>();
        list.add("周芷若");
        list.add("张无忌");
        list.add("赵敏");
        list.add("张三丰");
        list.add("张强");
        list.add("张翠山");


        //2.使用Stream流解决
        List<String> list2 = list.stream()  //把流理解为一个传送带,把集合里的所有数据扔到这个传送带上
                .filter(name -> name.startsWith("张"))  //过滤:把姓张的过滤出来 前面是数据 后面是过滤条件
                                                                      //返回一个新的流 这个流就只包含了姓张的人
                .filter(name -> name.length() == 3)     //过滤:把名字为3个字的过滤出来
                .collect(Collectors.toList());                //把符合条件的数据收集到新集合中去
        System.out.println(list2);

1.2-Stream流的使用步骤

  • 准备数据源(集合/数组/...)
  • 获取这个数据源的Stream流(Stream流代表一条流水线,并能与数据源建立连接。)
  • 调用流水线的各种方法,对数据进行处理计算(过滤、排序、去重...)
  • 获取处理的结果(遍历、同济、收集到一个新集合中返回)

2-获取Stream流

  • 获取集合的Stram流
//Collection类提供如下方法
default Stream<E> stream //获取当前集合对象的Stream流
  • 获取数组的Stream流
//Arrays类提供如下方法
public static <T> Stream<T> stream(T[] array)//获取当前数组对象的Stream流


//Stream类提供如下方法
public static<T> Stream<T> of(T...values)  //获取当前接收数据的Stream流

3-Stream流提供的常用方法

这一部分讲的就是Stream的中间方法,对于流水线上数据进行处理的部分。

有filiter过滤、sorted排序、按sorted照指定规则排序、limit获取前几个元素、skip跳过前几个元素、distinct去除流中重复的元素、map对元素进行加工,并返回对应的新流、concat合并a和b两个流为一个流...

  • 中间方法指的是调用完成后会返回新的Stream流,可以继续使用(支持链式编程)。

3.1方法代码实例

public static void main(String[] args) {
        //目标:掌握Stream提供的常用的中间方法,对流上的数据进行处理(返回新流,支持链式编程)
        List<String> list = new ArrayList<>();
        list.add("周芷若");
        list.add("张无忌");
        list.add("赵敏");
        list.add("张三丰");
        list.add("张强");
        list.add("张翠山");


        //1.过滤方法
        list.stream()
                .filter(name -> name.startsWith("张")&& name.length()==3).forEach(System.out::println);
        System.out.println("----------------------------------------------------------------");
        //2.排序方法。
        List<Double> list2 = new ArrayList<>();
        list2.add(30.10);
        list2.add(20.50);
        list2.add(10.10);
        list2.add(20.50);
        list2.add(40.00);
        list2.add(40.00);
        list2.add(50.50);
        list2.stream().sorted().forEach(System.out::println); //默认是升序。
        System.out.println("----------------------------------------------------------------");
        list2.stream().sorted((s1,s2)->Double.compare(s2, s1)).limit(3).forEach(System.out::println);//降序后只要前三名
        System.out.println("----------------------------------------------------------------");
        list2.stream().sorted((s1,s2)->Double.compare(s2, s1)).skip(2).forEach(System.out::println);//跳过前两名
        System.out.println("----------------------------------------------------------------");
        list2.stream().sorted((s1,s2)->Double.compare(s2, s1)).distinct().skip(2).forEach(System.out::println);//跳过前两名
        //这里是Double类,他类内已经重写了HashCode和equals,所以能自动去重和排序,如果是我们自定义的学生类,就需要重写HashCode和equals方法。
        System.out.println("----------------------------------------------------------------");
        //加工方法(映射方法):把流上原来的数据拿出来变成新数据又放到流上去。
        list2.stream().map(s->"加十分后:"+(s+10)).forEach(System.out::println);
        System.out.println("----------------------------------------------------------------");
        //合并流:把两个流接起来
        Stream<String> s1 = Stream.of("张无忌", "赵敏", "周芷若", "张强","牛马打工人");
        Stream<Integer> s2 = Stream.of(12,42,83,34,25,46,27,18,39);
        Stream<Object> s3=Stream.concat(s1,s2); //两个流类型不同,所以我们用Object类型,如果都是String类型,直接用String类型即可。
        s3.forEach(System.out::println);
    }


4-终结方法、收集Stream流

4.1-终结方法

终结方法指的是调用完成后,不会返回新Stream了,没法继续使用流了。

Stream提供的常用终结方法。

    //目标:掌握Stream中的收集操作(终结方法)
    List<Teacher> teachers = new ArrayList<>();
    teachers.add(new Teacher("张三", 30, 3000));
    teachers.add(new Teacher("程序员", 18, 14000));
    teachers.add(new Teacher("李四", 25, 5000));
    teachers.add(new Teacher("雷电将军", 25, 720020));
    teachers.add(new Teacher("工程师", 28, 50200));
    teachers.add(new Teacher("王五", 35, 7000));


    teachers.stream().filter(teacher -> teacher.getSalary() > 15000).forEach(System.out::println);//foreach后就不能再用stream流了,这就是终结方法
    System.out.println("----------------------------------------------------------------");
    long count = teachers.stream().filter(teacher -> teacher.getSalary() > 15000).count();//count()终结方法
    System.out.println(count);
    System.out.println("----------------------------------------------------------------");
    Optional<Teacher> max = teachers.stream().max((t1, t2) -> Double.compare(t1.getSalary(), t2.getSalary()));//max()终结方法
    Teacher maxteacher = max.get();
    System.out.println(maxteacher);


    Optional<Teacher> min = teachers.stream().min((t1, t2) -> Double.compare(t1.getSalary(), t2.getSalary()));//min()终结方法
    Teacher minteacher = min.get();
    System.out.println(minteacher);
}

运行结果

4.2收集Stream流

  • 收集Stream:就是把Stream流操作后的结果转回到集合或者数组中去返回。
  • Stream流:方便操作集合/数组的手段;集合/数组:才是开发中的目的
  • 流只能收集一次,流操作完一次,被收集后,是不能再收集的。

收集到List集合

收集到Set集合

收集到数组

收集到Map集合


5-综合案例前置条件

5.1-方法中可变参数

  • 就是一种特殊形参,定义在方法、构造器的形参列表里,格式是:数据类型...参数名称;

可变参数的特点和好处

  • 特点:可以不传数据给它;可以传一个或者同时传多个数据给它;也可以传一个数组给它。
  • 好处:常常用来灵活的接收数据。
public static void main(String[] args) {
        //目标:认识可变参数
        show(new int[]{1, 2, 3, 4, 5});//可以传数组
        show(1,2,3);//可以传多个参数
        show(1,2);//可以传两个参数
        show(1);//可以传一个参数
        show();//可以不传参数
        //优势:接收参数很灵活,可以替代数组传参。
    }
//    注意事项:可变参数在形参列表只能有一个,可变参数必须放在形参列表的最后面
    public static void show(int...nums){
        //内部怎么拿数据?
        //可变参数对内实际上就是一个数组,nums 就是数组。
        for (int i = 0; i < nums.length; i++) {
            System.out.println(nums.length);
            System.out.println(Arrays.toString(nums));
            System.out.println("-----------------------------------------------");
        }
    }

运行结果

5.2-Collections工具类

  • 是一个用来操作集合的工具类

Collections提供的常用静态方法

6-综合案例:斗地主小游戏

小游戏的结构

Card类

package com.xunshan.demo4Test;


import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;


@Data
@AllArgsConstructor
@NoArgsConstructor
public class Card {
    private String size;
    private String color;
    private int num;
    @Override
    public String toString() {
        return size+color;
    }
}

Room类

package com.xunshan.demo4Test;


import java.util.*;


public class Room {
    //1.准备好54张牌,给房间使用:定义一个集合容器装54张牌。
    //开发中不确定什么集合,就ArayList完事了
    private List<Card> allCards=new ArrayList<>();
    //2.初始化54张牌进去。
    {
        //3.准备点数
        String[] sizes={"3","4","5","6","7","8","9","10","J","Q","K","A","2"};
        //4.准备花色
        String[] colors={"♥","♠","♣","♦"};
        //5.组合点数和花色成为牌对象,加入到集合中去。
        int num=0;
        for (String size : sizes) {
            num++;
            for (String color : colors) {
                //6.创建牌对象 加入到牌集合中去
                allCards.add(new Card(size,color,num));
            }
        }
        allCards.add(new Card("小王","☆",++num));
        allCards.add(new Card("大王","★",++num));
        System.out.println("新牌是:"+allCards);
    }
    public void start() {
        //7.开始洗牌
        Collections.shuffle(allCards);
        System.out.println("洗牌后:"+allCards);
        //8.发牌:定义三个玩家:令狐冲=【】,令狐白=【】,令狐紫=【】
        Map<String,List<Card>> players=new HashMap<>();//令狐冲=【】,令狐白=【】,令狐紫=【】


        List<Card> lhc=new ArrayList<>();
        players.put("令狐冲",lhc);


        List<Card> lhb=new ArrayList<>();
        players.put("令狐白",lhb);


        List<Card> lhz=new ArrayList<>();
        players.put("令狐紫",lhz);


        //allCards=[54张牌]=[6♦, 7♦, J♦, 3♠, 6♥, 2♥, K♦, Q♦, 4♠, 7♥, J♣,...
        //只发出去51张
        for (int i = 0; i < allCards.size()-3; i++) {
            Card card = allCards.get(i);
            //判断当前牌应该发给谁
            if(i%3==0){
                //请阿冲揭牌
                lhc.add(card);
            }else if(i%3==1){
                //请阿白揭牌
                lhb.add(card);
            }else{
                //请阿紫揭牌
                lhz.add(card);
            }
        }


        //11.拿最后三张底牌
        List<Card> bottom=allCards.subList(allCards.size()-3,allCards.size());
        System.out.println("底牌是:"+bottom);


        //抢地主:把这个集合直接到给玩家
        lhz.addAll(bottom);


        //9.对牌排序
        sortCards(lhc);
        sortCards(lhb);
        sortCards(lhz);

        //10.看牌,遍历Map集合
        for (Map.Entry<String, List<Card>> entry : players.entrySet()) {
            //获取玩家名字
            String name = entry.getKey();
            //获取到玩家牌
            List<Card> cards = entry.getValue();
            //遍历玩家牌
            System.out.println(name+"的牌是:"+cards);
        }


    }


    private void sortCards(List<Card> cards) {
        Collections.sort(cards, new Comparator<Card>(){
            @Override
            public int compare(Card o1, Card o2) {
                return o1.getNum()-o2.getNum();
            }
        });
    }
}

Game类

package com.xunshan.demo4Test;


public class Game {
    public static void main(String[] args) {
        //目标:开发斗地主游戏
        //1.每张牌都是一个对象,定义牌类。
        //2.游戏房间也是一个对象,定义房间类(54张牌,开始启动)
        Room r=new Room();
        r.start();
    }
}

运行结果

每次运行的结果都是随机的,默认是令狐紫为地主,多三张牌,自动发牌,自动按大小排序。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/909309.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

练习LabVIEW第三十七题

学习目标&#xff1a; 刚学了LabVIEW&#xff0c;在网上找了些题&#xff0c;练习一下LabVIEW&#xff0c;有不对不好不足的地方欢迎指正&#xff01; 第三十七题&#xff1a; 利用XY GRAPH 构成李萨如图形 开始编写&#xff1a; 前面板放一个XY图控件&#xff0c;程序框图…

ubuntu20.04 加固方案-检查是否设置登录超时

一、编辑/etc/profile配置文件 打开终端。 使用文本编辑器&#xff08;如vim&#xff09;编辑/etc/profile 文件。 vi /etc/profile 二、添加配置参数 在打开的配置文件中&#xff0c;如图位置添加如下参数&#xff1a; TMOUT1800 export TMOUT三、保存并退出 在vim编辑器…

算法:图的相关算法

图的相关算法 1. 图的遍历算法1.1 深度优先搜索1.2 广度优先搜索 2. 最小生成树求解算法普里姆(Prim)算法克鲁斯卡尔(Kruskal)算法 3. 拓扑排序4. 最短路径算法 1. 图的遍历算法 图的遍历是指从某个顶点出发&#xff0c;沿着某条搜索路径对图中的所有顶点进行访问且只访问次的…

智能语音机器人智能在哪里?AI人工智能电话机器人部署

随着科技的不断进步&#xff0c;人工智能已经成为了我们生活中不可或缺的一部分。AI人工智能机器人电话正是其中的一种形式&#xff0c;可以帮助企业或组织更好地实现电话营销的目标&#xff0c;那么智能语音机器人智能在哪里?我们来看看&#xff1a; 智能语音机器人&#xf…

半波正弦信号的FFT变换

目录 Hello&#xff0c; 大家好&#xff0c;这一期我们谈谈半波正弦信号的FFT变化长什么样子。本文硬件使用GFARM02硬件模块[1]&#xff0c;文章最后有其淘宝链接。核心器件为STM32F103RCT6&#xff0c;为Cortex-M3核&#xff0c;采用的CMSIS版本为CMSIS_5-5.6.0。 如图1所示&…

计算机网络:网络层 —— 移动 IP 技术

文章目录 IPv6IPv6 的诞生背景主要优势IPv6引进的主要变化 IPv6数据报的基本首部IPv6数据报首部与IPv4数据报首部的对比 IPv6数据报的拓展首部IPv6地址IPv6地址空间大小IPv6地址的表示方法 IPv6地址的分类从IPv4向IPv6过渡使用双协议栈使用隧道技术 网际控制报文协议 ICMPv6ICM…

window 利用Putty免密登录远程服务器

1 在本地电脑用putty-gen生成密钥 参考1 参考2 2 服务器端操作 将公钥上传至Linux服务器。 复制上述公钥到服务器端的authorized_keys文件 mkdir ~/.ssh vi ~/.ssh/authorized_keys在vi编辑器中&#xff0c;按下ShiftInsert键或者右键选择粘贴&#xff0c;即可将剪贴板中的文…

词嵌入模型:Skip-Gram模型和CBOW模型

目录 Skip-Gram模型和CBOW模型 一、实现方式 二、训练目标 三、应用场景选择 Skip-Gram模型和CBOW模型 都是Word2Vec的两种实现方法,它们的确在实现方式和训练目标上有所不同,但共同的目标都是学习词汇的分布式表示(即词向量),以便捕捉词与词之间的语义和句法关系。以…

使用docker安装zlmediakit服务(zlm)

zlmediakit安装 zlmediakit安装需要依赖环境和系统配置&#xff0c;所以采用docker的方式来安装不容易出错。 docker pull拉取镜像(最新) docker pull zlmediakit/zlmediakit:master然后先运行起来 sudo docker run -d -p 1935:1935 -p 80:80 -p 8554:554 -p 10000:10000 -p …

微信小程序 uniapp+vue老年人身体监测系统 acyux

文章目录 项目介绍具体实现截图技术介绍mvc设计模式小程序框架以及目录结构介绍错误处理和异常处理java类核心代码部分展示详细视频演示源码获取 项目介绍 过此方式促进老年人辅助程序信息流动和数据传输效率&#xff0c;提供一个内容丰富、功能多样、易于操作的老年人辅助程序…

什么是Scaling Law,谈谈你对它的理解

1. 什么是Scaling Law 1.1 Scaling Law的目标 Having a sense of the capabilities of a model before training can improve decisions around alignment, safety, and deployment. — GPT4 Technical Report 在训练之前了解模型的能力&#xff0c;以改善关于大模型的对齐、…

Postgresql源码(137)执行器参数传递与使用

参考 《Postgresql源码&#xff08;127&#xff09;投影ExecProject的表达式执行分析》 0 总结速查 prepare p_04(int,int) as select b from tbl_01 where a $1 and b $2为例。 custom计划中&#xff0c;在表达式计算中使用参数的值&#xff0c;因为custom计划会带参数值&…

MMBench-Video:上海 AI Lab 联合多所高校推出长视频理解基准测试工具,全面评估 LVLMs 视频理解的能力

❤️ 如果你也关注大模型与 AI 的发展现状&#xff0c;且对大模型应用开发非常感兴趣&#xff0c;我会快速跟你分享最新的感兴趣的 AI 应用和热点信息&#xff0c;也会不定期分享自己的想法和开源实例&#xff0c;欢迎关注我哦&#xff01; &#x1f966; 微信公众号&#xff…

【万字详文介绍】:迭代扩张卷积神经网络(IDCNN)

&#x1f497;&#x1f497;&#x1f497;欢迎来到我的博客&#xff0c;你将找到有关如何使用技术解决问题的文章&#xff0c;也会找到某个技术的学习路线。无论你是何种职业&#xff0c;我都希望我的博客对你有所帮助。最后不要忘记订阅我的博客以获取最新文章&#xff0c;也欢…

(转载)Tools for Learning LLVM TableGen

前提 最近在学习有关llvm的东西&#xff0c;其中TableGen占了一部分&#xff0c;所以想特意学习下TableGen相关的语法。这里找到了LLVM官网的一篇介绍TableGen的博客&#xff0c;学习并使用机器翻译为中文。在文章的最后也添加了一些学习TableGen的资源。 原文地址&#xff1…

明源地产ERP WFWebService.asmx 反序列化RCE漏洞复现

0x01 产品简介 明源地产ERP是一款专为房地产行业设计的企业资源规划(ERP)系统,系统集成了项目管理、财务管理、客户关系管理、营销管理等多个模块,旨在帮助房地产企业提升运营效率、降低成本和提高客户满意度。它充分考虑了房地产行业的特性和需求,通过整合企业的各个业务…

AIGC时代LaTeX排版的应用、技巧与未来展望

文章目录 一、LaTeX简介与基础设置二、常用特殊符号与公式排版三、图片与表格的插入与排版四、自动编号与交叉引用五、自定义命令与样式六、LaTeX在AIGC时代的应用与挑战七、LaTeX的未来展望《LaTeX 入门实战》内容简介作者简介目录前言/序言读者对象本书内容充分利用本书 在AI…

redis:set集合命令,内部编码,使用场景

个人主页 &#xff1a; 个人主页 个人专栏 &#xff1a; 《数据结构》 《C语言》《C》《Linux》《网络》 《redis学习笔记》 文章目录 前言命令SADDSMEMBERSSISMEMBERSCARDSPOPSMOVESREM集合间操作SINTERSINTERSTORESUNIONSUNIONSTORESDIFFSDIFFSTORE 内部编码使用场景总结 前言…

智慧工地:引领工地管理和监测的革新

一、智慧工地是什么 智慧工地是智慧地球理念在工程领域的具体应用&#xff0c;是工程全生命周期管理的崭新理念。通过运用信息化手段&#xff0c;智慧工地利用三维设计平台对工程项目进行精确设计和施工模拟&#xff0c;重点关注施工过程管理&#xff0c;建立互联协同、智能生…

如何在Linux系统中使用Netcat进行网络调试

文章目录 Netcat简介安装Netcat在Debian/Ubuntu系统中安装在CentOS/RHEL系统中安装 Netcat基本命令Netcat基本用法示例1&#xff1a;监听端口示例2&#xff1a;连接到远程主机 Netcat选项-l选项-p选项-v选项 Netcat模式监听模式连接模式 Netcat排除和包含排除端口包含端口 Netc…