java进阶(Stream流,综合小案例)

Stream流

  • 可以用于操作集合或者数组的数据。

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

  • 不用流接收数据,最后会把Stream操作的结果转回到一个数组或者集合中去返回

  • 流只能收集一次

  • 处理步骤为:

    • 先得到集合或者数组的Stream流
    • 如何调用Stream流的方法对数据进行处理
    • 获取处理的结果
  • 举例:

    import java.util.ArrayList;
    import java.util.List;
    import java.util.stream.Collectors;
    
    public class Test {
        public static void main(String[] args) {
            List<String> list = new ArrayList<>();
            list.add("张三");
            list.add("李四");
            list.add("张乐乐");
            list.add("吴飞");
            list.add("张牛牛");
            //1.传统方法,找出姓张的人,并且名字为3个字的,存入到一个新集合里面
            List<String> list1 = new ArrayList<>();//新的集合
            for (String s : list) {
                if(s.startsWith("张")&&s.length()==3){
                    list1.add(s);
                }
            }
            System.out.println(list1);
    
            //2.Stream流方法
            //定义一个新集合存储数据,其中filter为过滤某个条件,collect为收集数据
            List<String> list2=list.stream().filter(s->s.startsWith("张")).filter(s->s.length()==3).collect(Collectors.toList());
            System.out.println(list2);
        }
    }
    
  • 获取Stream流:

    1. 获取集合的Stream流(单列Collection集合)

      Collection<String> list =new ArrayList<>();
      Stream<String> s1 = list.stream();
      
    2. 获取集合的Stream流(双列Map集合)

      Map<String,String> map =new HashMap<>();
      //获取键流
      Stream<String> s2 = map.keySet().stream();
      //获取值流
      Stream<String> s3 = map.values().stream();
      //获取键值对流
              Stream<Map.Entry<String, String>> s4 = map.entrySet().stream();
      
    3. 获取数组的流

      //获取数组的流
      String[] str={"a","b","c","d","e","f"};
      Stream<String> s5=Arrays.stream(str);
       System.out.println(a5.count());//6,取的是个数
      
      Stream<String> s6 = Stream.of(str);//Steam.of();里面可以设置任意类型的可变参数。
      
  • Stream常用的方法:

    //1.过滤方法
    list.stream().filter(s->s.startsWith("张")&&s.length()==3).forEach(System.out::println);
    //2.排序方法
    List<Double> list1 = new ArrayList<>();
    list1.add(54.5);
    list1.add(23.4);
    list1.add(65.7);
    list1.add(88.6);
    list1.add(88.6);
    list1.stream().sorted().forEach(System.out::println);//默认升序
    list1.stream().sorted((s1,s2)->Double.compare(s2,s1)).forEach(System.out::println);//重写sort方法变成降序
    
    //只要前两个数字
    list1.stream().sorted().limit(2).forEach(System.out::println);
    //跳过前两名
    list1.stream().sorted().skip(2).forEach(System.out::println);
    //去重,要是是引用类型对象,就要重写hashCode和equals方法
    list1.stream().distinct().forEach(System.out::println);
    //加工方法(映射方法),把流上原来的数据拿出来变成新数据又放到流上去
    list1.stream().map(s->"加十分后:"+(s+10)).forEach(System.out::println);
    //合并流
    Stream<String> s1 = Stream.of("qq","www","fdds","jjj");
    Stream<Integer> s2 = Stream.of(2,33,43,12,4);
    Stream<Object> stream = Stream.concat(s1,s2);//合并这两个流
    stream.forEach(System.out::println);
    
  • Stream流的终结方法:

    • void forEach();//遍历
    • long count();//统计个数
    • Optional max((t1,t2)->Double.compare(t1.getSum( ),t2.getSum( )));//取最大值,Optional为容器。
    • Optional min((t1,t2)->Double.compare(t1.getSum( ),t2.getSum( )));//取最小值
    //收集流到List集合中去,例:
    Stream<String>s1=list.stream().filter(s->s.startsWith("张"));
    List<String> ll=s1.collect(Collectors.toList());
    //收集流到Set集合中去,例:
    Set<String> ss=s1.collect(Collectors.toSet());
    //收集流到数组中去,例:
    Object[] ch=s1.toArray();
    //收集流到Map集合中去,将老师名字作为键,老师薪水作为值例:
    Map<String,Double> map=teachers.stream().collect(Collectors.toMap(Teacher::getName,Teacher::getSalary));
    
  • 可变参数:

    public class Test3 {
        public static void main(String[] args) {
            sum();
            sum(10);
            sum(12,23,43);//实际传入的是数组
        }
        //可变参数在形参列表中只能有一个,并且放在最后面
        public static void sum(int ...nums) {
            System.out.println(Arrays.toString(nums));
        }
    }
    

综合小案例

  • 斗地主的做牌,洗牌,发牌,对牌进行排序
package CardsDemo;

import java.util.*;

public class Service {
    //创建一个牌容器
    List<Card> cards = new ArrayList<>();
    //定义牌的花色和数字,还有大小
    String[] color = {"♥", "♦", "♠", "♣"};
    String[] number = {"3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A","2"};

    //创建一个方法来开始牌局
    public void start() {
        int size=0;//定义一个size来设定牌的大小
        //将花色和数字拼接存入牌堆
        for (int i = 0; i < number.length; i++) {
            size++;
            for (int j = 0; j < color.length; j++) {
                cards.add(new Card(number[i], color[j],size));
            }
        }
        //利用Collections方法来添加大小王
        Collections.addAll(cards, new Card("🃏", "",14), new Card("👲", "",15));
        System.out.println(cards.toString());

        //洗牌
        System.out.println("洗牌后牌堆为:");
        Collections.shuffle(cards);
        System.out.println(cards.toString());

        //定义三个玩家及其手上的牌存入Map集合
        Map<String, List<Card>> player = new HashMap<>();
        //第一个玩家
        List<Card> l1 = new ArrayList<>();
        player.put("小白", l1);
        //第二个玩家
        List<Card> l2 = new ArrayList<>();
        player.put("阿飞", l2);
        //第三个玩家
        List<Card> l3 = new ArrayList<>();
        player.put("小雨", l3);

        //遍历牌堆进行发牌,留下三张给地主的牌
        for (int i = 0; i < cards.size() - 3; i++) {
            if (i % 3 == 0) {
                l1.add(cards.get(i));
            }
            if (i % 3 == 1) {
                l2.add(cards.get(i));
            }
            if (i % 3 == 2) {
                l3.add(cards.get(i));
            }
        }
        //把最后的三张牌发给地主
        //存储最后三张牌
        List<Card> lastCards = cards.subList(cards.size() - 3, cards.size());
        //用随机数模拟谁抢到了地主
        Random r = new Random();
        int temp = r.nextInt(lastCards.size());
        String str="";
        switch (temp) {
            case 0:
                l1.addAll(lastCards);
                str="小白";
                break;
            case 1:
                l2.addAll(lastCards);
                str="阿飞";
                break;
            case 2:
                l3.addAll(lastCards);
                str="小雨";
                break;
        }
        System.out.println(str+"抢到了地主");
        //对每个人手里的牌进行排序

       player.forEach((k,v)->{
           sortCards(v);
       });
        //查看每个人手里的牌
        player.forEach((k, v) -> {
            System.out.println(k + "的牌为:" + v);
        });

    }
//一个排序的方法
    private void sortCards(List<Card> cards) {
        Collections.sort(cards, new Comparator<Card>() {
            @Override
            public int compare(Card o1, Card o2) {
                return o1.getSize()-o2.getSize();
            }
        });
    }
}
//牌类
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Card {
    private String color;
    private String number;
    private int size;

    @Override
    public String toString() {
        return  color + number ;
    }
}
//测试类:
public class Game {
    public static void main(String[] args) {
        //1.创建一个桌面来进行斗地主游戏
        Service service = new Service();
        service.start();
    }
}

//结果为:
[3♥, 3♦, 3♠, 3♣, 4♥, 4♦, 4♠, 4♣, 5♥, 5♦, 5♠, 5♣, 6♥, 6♦, 6♠, 6♣, 7♥, 7♦, 7♠, 7♣, 8♥, 8♦, 8♠, 8♣, 9♥, 9♦, 9♠, 9♣, 10♥, 10♦, 10♠, 10♣, J♥, J♦, J♠, J♣, Q♥, Q♦, Q♠, Q♣, K♥, K♦, K♠, K♣, A♥, A♦, A♠, A♣, 2♥, 2♦, 2♠, 2♣, 🃏, 👲]
洗牌后牌堆为:
[4♦, 10♠, K♦, J♦, 7♠, 6♣, 4♠, 8♥, K♥, J♣, 9♣, 10♦, 5♠, K♠, 2♥, 9♥, 5♣, 6♥, 8♦, 3♠, 3♣, 2♦, 7♦, 9♦, 5♥, 8♠, 8♣, 3♦, A♣, 7♥, 3♥, A♦, Q♣, 10♥, A♥, 5♦, Q♠, 👲, 9♠, J♥, Q♥, 🃏, J♠, 6♦, 2♣, A♠, Q♦, 4♣, 2♠, 7♣, K♣, 4♥, 10♣, 6♠]
阿飞抢到了地主
小雨的牌为:[3♣, 4♣, 5♦, 6♣, 6♥, 7♥, 8♣, 9♦, 9♠, 10♦, Q♣, K♦, K♥, K♣, 2♥, 2♣, 🃏]
小白的牌为:[3♦, 3♥, 4♦, 4♠, 5♠, 5♥, 8♦, 9♥, 10♥, J♦, J♣, J♥, J♠, Q♠, A♠, 2♦, 2♠]
阿飞的牌为:[3♠, 4♥, 5♣, 6♦, 6♠, 7♠, 7♦, 7♣, 8♥, 8♠, 9♣, 10♠, 10♣, Q♥, Q♦, K♠, A♣, A♦, A♥, 👲]
posted @ 2025-11-29 21:14  芒果学代码  阅读(0)  评论(0)    收藏  举报