当前位置: 首页 > 工具软件 > streama > 使用案例 >

【java8新特性】Stream流的操作及方法汇总

元叶秋
2023-12-01

Stream流

1、Stream介绍

Stream是一个,在java.util.Stream包路径下
主要作用就是对集合数据进行查找过滤等操作,一种高效且易用的数据处理方式
大数据领域有一个Stream流实时框架

Stream和Collection的区别就是:
Collection只是负责存储数据,不对数据做其他处理主要和内存打交道。
Stream主要是负责计算数据的,主要和CPU打交道(查询过滤)

2、Stream的操作

stream().后的操作汇总
方法作用
filter()接收lambda,从流中排除某些操作
limit()截断流,使其元素不超过给定对象
skip(n)跳过元素,返回一个扔掉了前n个元素的流,若流中元素不足n个,则返回一个空流,与limit(n)互补
distinct筛选,通过流所生成元素的hashCode()和equals去除重复元素
map接受Lambda,将元素转换成其他形式或提取信息。接受一个函数作为参数,该函数会被应用到每个元素上,并将其映射成一个新的元素
sorted()自然排序(Comparable)
sorted(Comparator com)定制排序(Comparator)
allMatch检查是否匹配所有元素
anyMatch检查是否至少匹配一个元素
noneMatch检查是否没有匹配所有元素
findFirst返回第一个元素
findAny返回当前流中的任意元素
count返回流中元素的总个数
max返回流中最大值
min返回流中最小值
reduce归约操作可以将流中元素反复结合起来,得到一个值
collect将流转换为其他形式,接收一个Collector接口实现,用于给Stream中汇总的方法

(流程较简单)
1、创建一个Stream:从一个数据源,如集合、数组中获取流
2、使用Stream操作数据:一个操作的中间链,对数据源的数据进行操作
3、终止Stream:一个终止操作,执行中间操作链,并产生结果

1)创建流

首先建一个数据源

public class Student  implements Comparable{
    private Integer id;
    private String name;
    private Integer age;
    private Double score;

    public Student(Integer id, String name, Integer age, Double score) {
        this.id = id;
        this.name = name;
        this.age = age;
        this.score = score;
    }

    public Integer getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    public Integer getAge() {
        return age;
    }

    public Double getScore() {
        return score;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public void setScore(Double score) {
        this.score = score;
    }

    @Override
    public int compareTo(Object o) {
       Student o1=(Student)o;return o1.getAge()-this.getAge();
    }

    @Override
    public String toString() {
        return "Student{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", age=" + age +
                ", score=" + score +
                '}';
    }
}

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

public class StudentData {
    public static List <Student> getStudents(){
        ArrayList <Student> students=new ArrayList<>();
        students.add(new Student(1,"jack",23,89.5));
        students.add(new Student(2,"jony",22,90.5));
        students.add(new Student(3,"Alice",22,87.1));
        students.add(new Student(4,"dack",24,89.7));
        return students;
    }
}

有四种创建流的方式

a、.stream()

调用stream()方法直接返回流

  public static void test1() {
        List<Student> students = StudentData.getStudents();
        Stream<Student> stream = students.stream();//第一种:返回一个顺序流
        Stream<Student> stream1 = students.parallelStream();//第二种:返回一个并行流
    }
b、Arrays.stream()
  //通过一个数组创建stream
    public static void test2(){
        //获取一个整型stream
        int []arr={1,34,2,54,56,34};
        IntStream stream = Arrays.stream(arr );
    }
c、stream.of
  public static void test3(){
        Stream<String> stringStream =Stream .of("1","4","34","23");
        Stream<Student>studentStream =Stream .of(new Student(1,"book",23,89.5),
                new Student(2,"cack",22,90.9));
    }
d、无限流
 //创建无限流
    public static void test4(){
        //每隔5个数取一个,从0开始,此时就会无限循环
        //t->t+5 ___________ for(int t=0;;){t+=5;}
        Stream <Integer>iterate=Stream.iterate(0,t->t+5);
        //取出一个随机数
        Stream <Double> generate=Stream.generate(Math ::random );
    }
2)使用流
a

操作一:筛选和切片
filter——接收lambda,从流中排除某些操作;
limit——截断流,使其元素不超过给定对象
skip(n)——跳过元素,返回一个扔掉了前n个元素的流,若流中元素不足n个,则返回一个空流,与limit(n)互补
distinct——筛选,通过流所生成元素的hashCode()和equals去除重复元素

public static void test5(){
        /**
         * 写成System.out::println这种语法叫做方法引用。该功能特性也是JDK8以后引入的,你可以把它看成lambdas表达式的语法糖
         * 可以用lambdas表达式改写成以下代码:list.forEach(t)-》System.out.println(t);
         * 这样还不明白的话,也可以这样:list.forEach(String t)-》System.out.println(t);
         * 这样的效果跟System.out::println是一样
         */
        List <Student> list=StudentData.getStudents();
        //过滤:过滤出所有年龄大于22岁的同学
        System.out.println("=============");
        list.stream().filter(item->item.getAge()>22).forEach(System.out::println);
        //截断流:筛选出前三条
        list.stream().limit(3).forEach(System.out::println);
        //跳过元素:跳过前两个元素
        list.stream().skip(2).forEach(System.out::println);
        System.out.println("================");
        //过滤重复元素
        list.stream().distinct().forEach(System.out::println);//没有重复的,根据hashcode判断
    }
b

操作二:映射
map——接受Lambda,将元素转换成其他形式或提取信息。接受一个函数作为参数,该函数会被应用到每个元素上,并将其映射成一个新的元素

 public static void test6(){
        //map操作
        List<String>list=Arrays.asList("hello","word","tulun");
        Stream<String> stream =list .stream() ;
        //将每一个小写字母都转换为大写字母映射
        stream .map(str ->str.toLowerCase()).forEach(System.out::println);

        //筛选出所有的年龄,再过滤出所有大于23的年龄
        List<Student>students =StudentData .getStudents() ;
        Stream <Student >stream1 =students .stream() ;
        //将流中的每一值转换为另一个值
        Stream <Integer >stream2 =stream1 .map(Student::getAge );
        stream2 .filter(age->age>23).forEach(System.out::println);
    }
c

操作三:排序
sorted()——自然排序(Comparable)
sorted(Comparator com)——定制排序(Comparator)

 public static void tset7(){
        //自然排序
        List <Integer >list=Arrays .asList(4,8,6,5,2,3,1,7);
        Stream<Integer >stream =list.stream() ;
        stream .sorted() .forEach(System.out::println );

        //对象排序,对象排序可以先实现comparable接口或者直接指定
        //第一种:先实现
        List<Student> students =StudentData .getStudents() ;
        students .stream() .sorted() .forEach(System.out::println);
        //第二种:直接指定
        List<Student> students1 =StudentData .getStudents() ;
        students1 .stream() .sorted((e1,e2)->(int)(e1.getScore() -e2.getScore() )).forEach(System.out::println);

    }
3)终止Stream
a

操作1:匹配和查找
*allMatch–检查是否匹配所有元素
*anyMatch–检查是否至少匹配一个元素
*noneMatch–检查是否没有匹配所有元素
*findFirst–返回第一个元素
*findAny–返回当前流中的任意元素
*count–返回流中元素的总个数
*max–返回流中最大值
*min–返回流中最小值

 public static void test8(){
        List<Student> list=StudentData.getStudents() ;
        //判断所有的学生年龄是否都大于20岁
        boolean allMatch=list.stream() .allMatch(student ->student .getAge() >20);
        //判断是否存在学生的年龄大于20岁
        boolean anyMatch=list .stream() .anyMatch(student ->student .getAge() >20);
        //判断是否不存在学生叫小白
        boolean noneMatch=list .stream() .noneMatch(student ->student .getName() .equals("小白") );
        //查找第一个学生
        Optional<Student>first=list .stream() .findFirst() ;
        //查找当前流中的元素
        Optional <Student>any=list .stream() .findAny() ;
        //查找所有的学生数量
        long count=list .stream() .count() ;
        //查找成绩大于90的数量
        long count1=list .stream() .filter(student ->student .getScore() >90).count() ;
        //查找学生的最高分数
        Stream <Double >doubleStream =list .stream() .map(student ->student .getScore() );
        Optional <Double > max=doubleStream .max(Double::compareTo );
        System.out.println(max );
    }

b

操作二:归约
*reduce–归约操作可以将流中元素反复结合起来,得到一个值

public static void test9(){
       //计算数的总和
       List<Integer >list =Arrays .asList(4,5,6,1,8,9,2,3,7) ;
       Integer reduce=list .stream() .reduce(0,Integer::sum );
       System.out.println(reduce );

       //计算学生总分
        List <Student >students =StudentData .getStudents() ;
        Stream <Double >doubleStream =students .stream() .map(Student::getScore );
        Optional <Double >reduce1=doubleStream .reduce(Double ::sum );
        System.out.println(reduce1 .get() );
    }
c

操作三:收集
*collect:将流转换为其他形式,接收一个Collector接口实现,用于给Stream中汇总的方法

  public static void test10(){
        //返回一个list
        List <Student >students =StudentData .getStudents() ;
        List <Student >list =students .stream() .filter(student ->student .getScore() >88).collect(Collectors.toList()) ;
        //返回一个set
        Set <Student >set =students .stream() .filter(s->s.getAge() >23).collect(Collectors.toSet()) ;
        System.out.println(set );
    }

3、Stream的优势

stream基本的语法就是这样,你会发现Stream就像是一个工具一样,可以帮我们分析处理数据,极其的好用,但是目前还不知道其效率如何
根据网上一位大佬的内存时间分析,其实在数据量比较庞大的时候,Stream可以为我们节省大量的时间

 类似资料: