当前位置: 首页 > news >正文

一篇文章速通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以姓张开始,并且长度为3list2.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;@Overridepublic 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>(){@Overridepublic 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();}
}

运行结果

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


http://www.mrgr.cn/news/66505.html

相关文章:

  • 基于redis实现延迟队列
  • 获得店铺所有商品:API的“商品大阅兵”
  • git clone,用https还是ssh
  • 软件设计师-上午题-16 算法(4-5分)
  • 一些关于云电脑与虚拟化东西
  • Java基础6-继承
  • 一文快速预览经典深度学习模型(一)——CNN、RNN、LSTM、Transformer、ViT
  • Vue:计算属性
  • JavaScript 变量作用域与函数调用机制:var 示例详解
  • SEO
  • 一个最简单的网络编程
  • OpenID Connect 和 OAuth 2.0 有什么不同?
  • Java继承练习
  • C++《list的模拟实现》
  • 通讯录(静态)
  • js基础篇笔记 (万字速通)
  • 【安装配置教程】二、VMware安装并配置ubuntu22.04
  • Kane-Mele X4Y2Z6材料自旋电子和谷电子理论研究
  • CSS的配色
  • 【数据分享】1981-2024年我国逐日平均气温栅格数据(免费获取)
  • 网络学习笔记---客户端和服务端
  • FBX福币交易所A股三大指数小幅低开 稀土永磁板块回调
  • Oracle OCP认证考试考点详解082系列12
  • 简易CPU设计入门:译码模块(一)
  • 【英特尔IA-32架构软件开发者开发手册第3卷:系统编程指南】2001年版翻译,2-14
  • MySQL学习正式篇