JDK8新特性之Stream流

目录

一、简介

二、Stream流的应用

2.1 为什么使用stream流

2.2 Stream流的原理

 2.3 步骤

 2.4 获取Stream流对象的方式

2.5 Stream流的API方法

2.5.1 map

2.5.2 collect 收集

2.5.3  sorted 排序

2.5.4 reduce 规约

2.5.5 findFirst 查询第一个


一、简介

Java8的两个重大改变,一个是Lambda表达式,另一个就是本节要讲的Stream API表达式。Stream 是Java8中处理集合的关键抽象概念,它可以对集合进行非常复杂的查找、过滤、筛选等操作

二、Stream流的应用

2.1 为什么使用stream流

当我们对集合中的元素进行操作的时候,除了必须的添加、删除、获取外,最典型的就是集合遍历。我们可以来展示一下集合操作数据的弊端,需求如下:

需求:

        一个ArrayList集合中存储有以下数据:张无忌,周芷若,赵敏,孙悟空,张三丰,张三
        1.拿到所有姓张的 2.拿到名字长度为3个字的 3.打印这些数据

package demo01;

import java.util.ArrayList;
import java.util.List;

/**
 * @author huihui
 * @Project jdk8_stream
 * @date 2023/6/14 14:28
 */
public class Test {
    //        一个ArrayList集合中存储有以下数据:张无忌,周芷若,赵敏,孙悟空,张三丰,张三
    //        需求:1.拿到所有姓张的 2.拿到名字长度为3个字的 3.打印这些数据
    public static void main(String[] args) {
        List list = new ArrayList<>();
        list.add("张无忌");
        list.add("周芷若");
        list.add("赵敏");
        list.add("孙悟空");
        list.add("张三丰");
        list.add("张三");

        //1. 拿到所有姓张的人名
        List newList01 = new ArrayList<>();
        for (String s : list) {
            if(s.startsWith("张")){//startsWith--以...开头
                newList01.add(s);
            }
        }

        //2.拿到名字长度为3个字的
        ArrayList newList02 = new ArrayList<>();
        for (String s : newList01) {
            if(s.length()==3){
                newList02.add(s);
            }
        }

        //3.打印这些数据
        for (String s : newList02) {
            System.out.println(s);
        }
    }
}

分析:

循环遍历的弊端

这段代码中含有三个循环,每一个的作业都不同

        1.首先筛选张姓的人

        2.然后筛选名字有三个字的人

        3.最后进行对结果进行打印输出

每当我们需要对集合中的元素进行操作的时候,总是需要进行循环、循环、再循环。这是理所当然的么?不是。循环 是做事情的方式,而不是目的。每个需求都要循环一次,还要搞一个新集合来装数据,如果希望再次遍历,只能再使 用另一个循环从头开始。

那Stream能给我们带来怎样更加方便的写法呢?

Stream初体验

package demo01;

import java.util.ArrayList;
import java.util.List;

/**
 * @author huihui
 * @Project jdk8_stream
 * @date 2023/6/14 14:28
 */
public class Test {
    //        一个ArrayList集合中存储有以下数据:张无忌,周芷若,赵敏,孙悟空,张三丰,张三
    //        需求:1.拿到所有姓张的 2.拿到名字长度为3个字的 3.打印这些数据
    public static void main(String[] args) {
        List list = new ArrayList<>();
        list.add("张无忌");
        list.add("周芷若");
        list.add("赵敏");
        list.add("孙悟空");
        list.add("张三丰");
        list.add("张三");

        list.stream().filter(t->t.startsWith("张")).filter(t->t.length()==3).forEach(item-> System.out.println(item));

    }
}

2.2 Stream流的原理

Stream流式思想类似于工厂车间的“生产流水线”,Stream流不是一种数据结构,不保存数据,而是对数据进行加工 处理。Stream可以看作是流水线上的一个工序。在流水线上,通过多个工序让一个原材料加工成一个商品。

JDK8新特性之Stream流_第1张图片

 2.3 步骤

  1. 获取Stream流对象
  2. 中间操作---返回类型还是Stream流对象
  3. 终止操作---不再是Stream流对象

JDK8新特性之Stream流_第2张图片

 2.4 获取Stream流对象的方式

  1. 通过集合对象调用stream()
  2. 通过Arrays获取stream流对象
  3. 通过Stream流里面of方法
package demo02;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;

/**
 * @author huihui
 * @Project jdk8_stream
 * @date 2023/6/14 15:36
 */
public class Test02 {
    public static void main(String[] args) {
        //第一种通过集合对象调用
        List list=new ArrayList<>();
        Stream stream = list.stream();
        //第二种使用Arrays工具类
        String[] arr={};
        Stream stream1 = Arrays.stream(arr);
        //第三种:Stream类
        Stream stream2 = Stream.of(1,2,3,4,5,6);
        //上面都是串行流
    }
}
  • 还有一种并行流(效率提高,但不确定输出顺序)
package demo02;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;

/**
 * @author huihui
 * @Project jdk8_stream
 * @date 2023/6/14 15:36
 */
public class Test02 {
    public static void main(String[] args) {
        List list=new ArrayList<>();
        list.add("张无忌");
        list.add("周芷若");
        list.add("赵敏");
        Stream stringStream = list.parallelStream();
        stringStream.forEach(System.out::println);
    }
}

2.5 Stream流的API方法

例子:

        假设有一个Person类和一个Person列表,现在有两个需求:

             1.   找到年龄大于18岁的人并输出;

             2.   找出所有中国人的数量。

             3.   找出年龄最大和最小

package demo03;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;

/**
 * @author huihui
 * @Project jdk8_stream
 * @date 2023/6/14 15:52
 */
public class Test03 {
    public static void main(String[] args) {
        List personList = new ArrayList<>();
        personList.add(new Person("欧阳雪",18,"中国",'F'));
        personList.add(new Person("Tom",24,"美国",'M'));
        personList.add(new Person("Harley",22,"英国",'F'));
        personList.add(new Person("向天笑",20,"中国",'M'));
        personList.add(new Person("李康",22,"中国",'M'));
        personList.add(new Person("小梅",20,"中国",'F'));
        personList.add(new Person("何雪",21,"中国",'F'));
        personList.add(new Person("李康",22,"中国",'M'));
        //1. 年龄大于18  filter:过滤掉不满足条件的元素.  forEach:输出元素. ---如果没有终止函数,那么中间函数的代码不会被执行。
        personList.stream().filter(item->item.getAge()>18).forEach(System.out::println);

        //2. 找出中国人  并统计个数: count()
        long count = personList.stream().filter(item -> item.getCountry().equals("中国")).count();
        System.out.println("中国人的数量为:"+count);

        //3.找出年龄最大和最小
        Person person1 = personList.stream().max((o1, o2) -> o1.getAge() - o2.getAge()).get();
        Person person2 = personList.stream().min((o1, o2) -> o1.getAge() - o2.getAge()).get();
        System.out.println("年龄最大:"+person1);
        System.out.println("年龄最小:"+person2);
    }
}

class Person {
    private String name;
    private Integer age;
    private String country;
    private char sex;

    public Person() {
    }

    public Person(String name, Integer age, String country, char sex) {
        this.name = name;
        this.age = age;
        this.country = country;
        this.sex = sex;
    }

    /**
     * 获取
     * @return name
     */
    public String getName() {
        return name;
    }

    /**
     * 设置
     * @param name
     */
    public void setName(String name) {
        this.name = name;
    }

    /**
     * 获取
     * @return age
     */
    public Integer getAge() {
        return age;
    }

    /**
     * 设置
     * @param age
     */
    public void setAge(Integer age) {
        this.age = age;
    }

    /**
     * 获取
     * @return country
     */
    public String getCountry() {
        return country;
    }

    /**
     * 设置
     * @param country
     */
    public void setCountry(String country) {
        this.country = country;
    }

    /**
     * 获取
     * @return sex
     */
    public char getSex() {
        return sex;
    }

    /**
     * 设置
     * @param sex
     */
    public void setSex(char sex) {
        this.sex = sex;
    }

    public String toString() {
        return "Person{name = " + name + ", age = " + age + ", country = " + country + ", sex = " + sex + "}";
    }
}

2.5.1 map

会把集合中的元素转化为另一种类型

JDK8新特性之Stream流_第3张图片

 如上述案例---查询到来自中国的人民和年龄

 personList.stream().filter(item->item.getCountry().equals("中国")).map(item->new P(item.getName(),item.getAge())).forEach(System.out::println);

案例2:

package demo04;

import java.util.Arrays;
import java.util.List;

/**
 * @author huihui
 * @Project jdk8_stream
 * @date 2023/6/14 16:18
 */
public class Test04 {
    public static void main(String[] args) {
        //整数数组每个元素+3
        List list = Arrays.asList(1, 17, 27, 7);
        list.stream().map(item -> item + 3).forEach(System.out::println);

        List list2 = Arrays.asList("hello", "world", "java", "spring", "springmvc");
        //字符串大写
        list2.stream().map(String::toUpperCase).forEach(System.out::println);
    }
}

2.5.2 collect 收集

package demo05;



import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author huihui
 * @Project jdk8_stream
 * @date 2023/6/14 16:21
 */
public class Test05 {
    public static void main(String[] args) {
      List personList = new ArrayList<>();
      personList.add(new Person5("小梅",24,"中国",'F'));
      personList.add(new Person5("欧阳雪",18,"中国",'F'));
      personList.add(new Person5("Tom",24,"美国",'M'));
      personList.add(new Person5("Harley",22,"英国",'F'));
      personList.add(new Person5("向天笑",20,"中国",'M'));
      personList.add(new Person5("李康",22,"中国",'M'));
      personList.add(new Person5("Jack",21,"中国",'F'));
      personList.add(new Person5("李四",22,"中国",'M'));
      //把Person-年龄大于20人--里面的名称----新的集合。
      personList.stream().filter(item->item.getAge()>20).map(item->item.getName()).collect(Collectors.toList()).forEach(System.out::println);
    }
}
class Person5{
  private String name;
  private Integer age;
  private String country;
  private char sex;

  public Person5() {
  }

  public Person5(String name, Integer age, String country, char sex) {
    this.name = name;
    this.age = age;
    this.country = country;
    this.sex = sex;
  }

  /**
   * 获取
   * @return name
   */
  public String getName() {
    return name;
  }

  /**
   * 设置
   * @param name
   */
  public void setName(String name) {
    this.name = name;
  }

  /**
   * 获取
   * @return age
   */
  public Integer getAge() {
    return age;
  }

  /**
   * 设置
   * @param age
   */
  public void setAge(Integer age) {
    this.age = age;
  }

  /**
   * 获取
   * @return country
   */
  public String getCountry() {
    return country;
  }

  /**
   * 设置
   * @param country
   */
  public void setCountry(String country) {
    this.country = country;
  }

  /**
   * 获取
   * @return sex
   */
  public char getSex() {
    return sex;
  }

  /**
   * 设置
   * @param sex
   */
  public void setSex(char sex) {
    this.sex = sex;
  }

  public String toString() {
    return "Person5{name = " + name + ", age = " + age + ", country = " + country + ", sex = " + sex + "}";
  }
}

2.5.3  sorted 排序

//根据年龄排序
      List collect = personList.stream().sorted((o1, o2) -> o1.getAge() - o2.getAge()).collect(Collectors.toList());
      System.out.println(collect);

2.5.4 reduce 规约

归约,也称缩减,顾名思义,是把一个流缩减成一个值,能实现对集合求和、求乘积和求最值操作。

JDK8新特性之Stream流_第4张图片

 例子:

        求[1,2,3,4]的乘积

package demo06;

import java.util.Arrays;
import java.util.List;
import java.util.Optional;

/**
 * @author huihui
 * @Project jdk8_stream
 * @date 2023/6/14 16:30
 */
public class Test06 {
    public static void main(String[] args) {
        List list = Arrays.asList(1, 2, 3, 5);
        Optional reduce = list.stream().reduce((t1, t2) -> t1 * t2);
        //t1=1, t2=2 ===>2
        // t1=2  t2=3===>6
        // t1=6  t2=5====>30
        System.out.println(reduce.get());
    }
}

2.5.5 findFirst 查询第一个

      //查询年龄在18和20直接的一个
      Optional first = personList.stream().filter(item->item.getAge()>=18&&item.getAge()<=20).findFirst();
      System.out.println(first.get());

你可能感兴趣的:(数学建模)