Stream流式思想

Stream是Java8引入的新特性,它提供了一种更简洁、可读性更好的方式来操作集合或数组数据。通过Lambda表达式,可以方便地进行过滤、排序、收集等操作。例如,从一个姓名列表中筛选出以张开头且长度为3的姓名。StreamAPI包含中间方法如filter、sorted和终结方法如forEach、collect,支持链式编程,使得数据处理更高效。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

什么是Stream?

也叫Stream流,是Jdk8开始新增的一套API (java.util.stream.*),可以用于操作集合或者数组的数据。
优势: Stream流大量的结合了Lambda的语法风格来编程,提供了一种更加强大,更加简单的方式操作集合或者数组中的数据,代码更简洁,可读性更好。

要使用Stream流,先检查自己电脑上配置的jdk版本是否在8以上,不是的话该更新了哦,Stream尊嘟好好玩。

jdk17下载链接在这里的呢,https://download.oracle.com/java/17/latest/jdk-17_windows-x64_bin.msi

体验Stream流

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

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

  • 解题分析:我们先来分析一下题意,1、以张开头的姓名 2、姓名是三个字

  • list集合调用stream()方法转为Stream流,再调用Stream流的相关方法

  • filter筛选出符合条件的对象,collect()方法收集生成的对象,Collectors.toList()把收集后的对象存储到List集合当中

  • List<String> names = new ArrayList<>();
            Collections.addAll(names, "张三丰", "张无忌", "周芷若", "赵敏", "张强");
            // 开始使用Stream流来解决这个需求。
            List<String> newNames = names
                    .stream()
                    .filter(name -> name.startsWith("张") && name.length() == 3)
                    .collect(Collectors.toList());
            System.out.println("newNames = " + newNames);
            System.out.println("---------------------------------------");
            //不想存储到集合的话,也可以直接调用foreach方法,直接输出,效果等同
            names.stream()
                    .filter(name -> name.startsWith("张") && name.length() == 3)
                    .forEach(System.out::println);
    

除了用传统方法逐个进行添加之外,我们也可以直接使用 Collections工具类,调用addAll方法进行添加String对象

比如,介样子 List names = new ArrayList<>();
Collections.addAll(names, “张三丰”, “张无忌”, “周芷若”, “赵敏”, “张强”);

Stream流的常用方法

       TreeMap<String, ArrayList<String>> citys = new TreeMap<>();
        ArrayList<String> su = new ArrayList<>();
        ArrayList<String> e = new ArrayList<>();
                ArrayList<String> ji = new ArrayList<>();
                Collections.addAll(su, "南京", "扬州", "苏州", "无锡", "常州");
                Collections.addAll(e, "武汉市", "孝感市", "十堰市", "宜昌市", "鄂州市");
                Collections.addAll(ji, "石家庄市", "唐山市", "邢台市", "保定市", "张家口市");
                citys.put("江苏省", su);
                citys.put("湖北省", e);
                citys.put("河北省", ji);
                ArrayList<String> strings = citys.get("湖北省");
                strings.forEach(System.out::println);


//迭代器遍历查找,根据键找值,再逐层进行筛选
                Set<Map.Entry<String, ArrayList<String>>> entries = citys.entrySet();
                Iterator<Map.Entry<String, ArrayList<String>>> iterator = entries.iterator();
                while (iterator.hasNext()) {
                    Map.Entry<String, ArrayList<String>> next = iterator.next();
                    String key = next.getKey();
                    //找到合适的键,进行匹配,符合要求之后输出键对应的值
                    if (key.equals("湖北省")) {
                ArrayList<String> nextValue = next.getValue();
                nextValue.forEach(System.out::println);
            }
        }
        Set<String> strings1 = citys.keySet();
        ArrayList<String> strings2 = citys.get("江苏省");
//Steam流式思想,调用双层forEach方法,逐级调用里面的对象元素
        citys.forEach((key, city) -> {
            System.out.print(key + ":");
            city.forEach(System.out::println);
        });
    }
}

Stream流的使用步骤

  • 获取Stream流,Stream流代表一条流水线,并能与数据源建立连接。
  • 调用流水线的各种方法对数据进行处理、计算。
  • 获取处理的结果,遍历、统计、收集到一个新集合中返回

1、Stream是什么?有什么作用? 结合了什么技术?
简化集合、数组操作的API。结合了Lambda表达式。

2、说说Stream流处理数据的步骤是什么?
先得到集合或者数组的Stream流。
然后调用Stream流的方法对数据进行处理。
获取处理的结果。

Stream流训练:

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

//concat 拼接方法
      Stream<String> str1 = Stream.of("A", "B", "C");
      Stream<String> str2 = Stream.of("1", "2", "3");
      //拼接流str1和str2
      Stream.concat(str1,str2)
              .forEach(System.out::println);
//拼接流str1和str2
      List<String> collect = Stream.concat(Stream.of(names), Stream.of(signal)).collect(Collectors.toList());
      collect.stream().forEach(System.out::println);

获取Stream流

  • Collection提供了专门的集合对象Stream流获取方法,default Stream stream()

  • 获取 集合 的Stream流

    • List<String> list = new ArrayList<>();
      Stream<String> stream = names.stream();//集合直接调用stream()方法,获取Stream流
      
  • 获取 数组 的Stream流

    • 数组获取Stream流的方式有两种,使用Arrays类和Stream类

    • Arrays类提供的Stream方法获取当前数组的Stream流

    • Stream类提供的方法of(T… values)获取当前接收数据的Stream流

    • int[] a = {1, 2, 3, 4, 5, 6};
      String[] str = new String[]{"A", "B", "C"};
      //public static <T> Stream<T> stream(T[] array)  
      Arrays.stream(a).forEach(System.out::println);//先转为Stream流,才可以调用Stream流里面的相关方法
      //public static<T> Stream<T> of(T... values)
      Stream.of(str).forEach(System.out::println);
      

Stream流常见的中间方法

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

  • Stream<T> filter(Predicate<? super T> predicate)            //用于对流中的数据进行过滤。       
    Stream<T>sorted()                                           //对元素进行升序排序               
    Stream<T> sorted(Comparator<? super T> comparator)          //按照指定规则排序                
    Stream<T>limit(long maxSize)                                //获取前几个元素                  
    Stream<T> skip(long n)                                      //跳过前几个元素                  
    Stream<T> distinct()                                        //去除流中重复的元素。             
    <R> Stream<R> map(Function<? super T,? extends R> mapper)   //对元素进行加工,并返回对应的新流 
    static <T> Stream<T> concat**(Stream a, Stream b)           //合并a和b两个流为一个流           
    

Stream常见的终结方法

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

  • void forEach(Consumer action)							//对此流运算后的元素执行遍历
    long count()										   //统计此流运算后的元素个数
    Optional<T> max(Comparator<? super T> comparator)          //获取此流运算后的最大值元素
    Optional<T> min(Comparator<? super T> comparator)          //获取此流运算后的最小值元素
    

Stream流常见方法、中间方法、终结方法的综合实战

  • 实战目标:掌握Stream流提供的常见、中间、终结方法。

  • 前期数据准备

    • import java.util.Objects;
      public class Student {//学生类
          private String name;//姓名
          private int age;//年龄
          private double height;//身高
          private String sex;//性别
          private String address;//家庭地址
          @Override
          public String toString() {
              return "学生姓名:" + name + ", 年龄:"
                      + age + ", 身高:" + height + ", 性别:" + sex + ", 家庭住址:" + address +'。';
          }
          public String getSex() {
              return sex;
          }
          public void setSex(String sex) {
              this.sex = sex;
          }
          public String getAddress() {
              return address;
          }
          public void setAddress(String address) {
              this.address = address;
          }
          public Student() {
          }
          public Student(String name, int age, double height,String sex,String address) {
              this.name = name;
              this.age = age;
              this.height = height;
              this.sex = sex;
              this.address = address;
          }
          public String getName() {
              return name;
          }
          public void setName(String name) {
              this.name = name;
          }
          public int getAge() {
              return age;
          }
          public void setAge(int age) {
              this.age = age;
          }
          public double getHeight() {
              return height;
          }
          public void setHeight(double height) {
              this.height = height;
          }
          @Override
          public boolean equals(Object o) {
              if (this == o) return true;
              if (o == null || getClass() != o.getClass()) return false;
              Student student = (Student) o;
              return Objects.equals(name, student.name);
          }
          @Override
          public int hashCode() {
              return Objects.hash(name);
          }
      }
      
    • Student s1 = new Student("林风", 26, 172.5,"男","苏州市");
      Student s2 = new Student("赵琳", 26, 162.5,"女","兰州市");
      Student s3 = new Student("音音", 23, 160.6,"女","西安市");
      Student s4 = new Student("姜维", 25, 169.0,"男","天水市");
      Student s5 = new Student("林锋", 35, 183.3,"女","深圳市");
      Student s6 = new Student("李广", 34, 168.5,"男","天水市");
      

    训练1:已知如下数据,找出成绩大于等于60分的数据,并升序后,再输出。

    • List<Double> scores = new ArrayList<>();
      Collections.addAll(scores, 88.5, 100.0, 60.0, 99.0, 9.5, 99.6, 25.0);
      
    • 解题过程:

      • // 因为分数是double类型,排序的时候直接调用double的封装类Double进行排序
         scores.stream()
               .filter(score->(score>=60))
               .sorted((o1,o2)->Double.compare(o1,o2))
               .forEach(System.out::println);
        

    训练2:已知students学生集合,找出年龄大于等于23,且年龄小于等于30岁的学生,并按照年龄降序输出.

    • 解题过程:

      students.stream()
              .filter(student -> student.getAge()>=23&&student.getAge()<=30)
              .sorted(((o1,o2)-> Integer.compare(o2.getAge(),o1.getAge())))
              .forEach(System.out::println);
       //首先转换为stream流,然后调用filter进行筛选,再降序最后打印输出列表内容,严格按照题意
      

    训练3:已知students学生集合,取出身高最高的前3名学生,并输出。

    • 解题过程

          students.stream()
                    .sorted(((o1,o2)-> Double.compare(o2.getHeight(),o1.getHeight())))
                    .limit(3)
                    .forEach(System.out::println);
      

    训练4:取出身高倒数2名学生,并输出学生信息。

    • 解题过程

      students.stream()
                     .sorted(((o1,o2)-> Double.compare(o1.getHeight(),o2.getHeight())))
                     .limit(2)
                     .forEach(System.out::printn);
      

    训练5:找出身高超过168的学生叫什么名字,要求去除重复的名字,再输出。

    • 解题过程

      students.stream()
        		.filter(student -> student.getHeight()>=168)
             .map(stu->stu.getName())// 使用Map方法将学生对象转换为名字数据
             .distinct()//名字字符串的去重
             .forEach(System.out::println);
      /**distinct去重复,自定义类型的对象(希望内容一样就认为重复,重写hashCode,equals)
              学生集合中的数据是学生对象,要求获取学生的名字,并且去重输出。
              如何在Stream中将Student数据转换为String数据? 可以使用map方法完成转换**/
      
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

火飞鹰

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值