Java8中Stream()流的用法总结

简单的集合遍历

foreach遍历

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

/**
 * @author rx
 * @date 2022/6/1 17:18
 */
public class Demo1Foreach {
    public static void main(String[] args) {
        List<String>list=new ArrayList<>();
        list.add("w2");
        list.add("zh3");
        list.add("l4");
        list.add("lao6");
        list.add("tomas");
        for (String s:list){
            System.out.println(s);
        }
    }
}

  迭代器遍历

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

/**
 * @author rx
 * @date 2022/6/1 17:18
 */
public class Demo1Foreach {
    public static void main(String[] args) {
        List<String>list=new ArrayList<>();
        list.add("w2");
        list.add("zh3");
        list.add("l4");
        list.add("lao6");
        list.add("tomas");
        Iterator<String> iterator = list.iterator();
        while (iterator.hasNext()){
            System.out.println(iterator.next()+"\t");
        }
    }
}

 有以下场景

  1. 将集合A根据条件一过滤为子集B;
  2. 然后再根据条件二过滤为子集C。

先使用Java8以前的做法

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

/**
 * @author rx
 * @date 2022/6/1 17:18
 */
public class Demo1Foreach {
    public static void main(String[] args) {

        List<String>list=new ArrayList<>();
        List<String>listA=new ArrayList<>();
        List<String>listB=new ArrayList<>();
        list.add("w2");
        list.add("zh3");
        list.add("l4");
        list.add("lao6");
        list.add("tomas");
       for (String s:list){
           if (s.startsWith("l")){
               listA.add(s);
           }
       }
       for (String s:listA){
           if (s.length()==4){
               listB.add(s);
           }
       }
        for (String s:listB){
            System.out.println(s);
        }
    }
}

  使用Stream()流更优的写法

1.场景一:筛选

1.1 基于filter()实现数据过滤

该方法会接收一个返回boolean的函数作为参数,终返回一个包括所有符合条件元素的流。

import jdk.nashorn.internal.ir.IfNode;

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

/**
 * @author rx
 * @date 2022/6/1 17:18
 */
public class StreamDemo1 {
    public static void main(String[] args) {

        List<String>list=new ArrayList<>();
        List<String>listA=new ArrayList<>();
        List<String>listB=new ArrayList<>();
        list.add("w2");
        list.add("zh3");
        list.add("l4");
        list.add("lao6");
        list.add("tomas");
       list.stream().filter(
               name->name.startsWith("l")
       ).filter(
               name->name.length()==4
       ).forEach(name-> System.out.println(name));
    }
}

  

import jdk.nashorn.internal.ir.IfNode;

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

/**
 * @author rx
 * @date 2022/6/1 17:18
 */
public class StreamDemo2 {
    public static void main(String[] args) {
        List<Student>students=new ArrayList<>();
        students.add(new Student("wang2",5,"f"));
        students.add(new Student("zh3",3,"f"));
        students.add(new Student("li4",5,"f"));

         students.stream().filter(student ->
                student.getName().length() == 3
                        && student.getAge() < 5
        ).forEach(System.out::println);
    }
}

class Student {
    public Student(String name, int age, String gender) {
        this.name = name;
        this.age = age;
        this.gender = gender;
    }

    public String getName() {
        return name;
    }

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

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

    public int getAge() {
        return age;
    }

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

    public String getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }

    private String name;
    private int age;
    private String gender;


}

 1.2基于distinct实现数据去重

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

/**
 * @author rx
 * @date 2022/6/3 10:04
 */
public class StreamDemo3 {
    public static void main(String[] args) {
        List<Integer> numbers = Arrays.asList(1, 2, 4, 5, 3, 2, 1, 3, 4, 5, 6, 5, 7, 8);
        numbers.stream().distinct().forEach(System.out::println);
    }
}

  在distinct()内部是基于LinkedHashSet对流中数据进行去重,并终返回一个新的流。

2.切片

2.1基于limit()实现数据截取

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

/**
 * @author rx
 * @date 2022/6/3 10:04
 */
public class StreamDemo5 {
    public static void main(String[] args) {
        List<Integer> numbers = Arrays.asList(1, 2, 4, 5, 3, 2, 1, 3, 4, 5, 6, 5, 7, 8);
        numbers.stream().limit(3).forEach(System.out::println);
    }
}

2.2基于skip()实现数据跳过

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

/**
 * @author rx
 * @date 2022/6/3 10:04
 */
public class StreamDemo6 {
    public static void main(String[] args) {
        List<Integer> numbers = Arrays.asList(1, 2, 4, 5, 3, 2, 1, 3, 4, 5, 6, 5, 7, 8);
        numbers.stream().skip(3).forEach(System.out::println);
    }
}

 3.映射

在Stream API中也提供了类似的方法,map()。它接收一个函数作为方法参数,这个函数会被应用到集合中每一个 元素上,并终将其映射为一个新的元素。 案例:获取所有学生的姓名,并形成一个新的集合。

public class StreamDemo7 {
    public static void main(String[] args) {
        List<Student>students=new ArrayList<>();
        students.add(new Student("wang2",5,"f"));
        students.add(new Student("zh3",3,"f"));
        students.add(new Student("li4",5,"f"));

        List<String> stringList = students.stream().map(student -> student.getName()).collect(Collectors.toList());
        stringList.stream().forEach(System.out::println);

    }
}

4、匹配

boolean anyMatch()、boolean allMatch()、boolean noneMatch()方法。

import jdk.nashorn.internal.ir.IfNode;

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

/**
 * @author rx
 * @date 2022/6/1 17:18
 */
public class StreamDemo8 {
    public static void main(String[] args) {
        List<Student>students=new ArrayList<>();
        students.add(new Student("wang2",5,"f"));
        students.add(new Student("zh3",3,"f"));
        students.add(new Student("li4",5,"f"));

if (students.stream().allMatch(student -> student.getAge()<5)){
    System.out.println("have ");
        }else {
    System.out.println("don't");
}
    }
}

5.查找

对于集合操作,有时需要从集合中查找中符合条件的元素,Stream中也提供了相关的API,findAny()和 findFirst(),他俩可以与其他流操作组合使用。findAny用于获取流中随机的某一个元素,findFirst用于获取流中的 第一个元素。至于一些特别的定制化需求,则需要自行实现。

 

5.1基于findAny()查找元素

案例:findAny用于获取流中随机的某一个元素,并且利用短路在找到结果时,立即结束

public class StreamDemo9 {
    public static void main(String[] args) {
        List<Student>students=new ArrayList<>();
        students.add(new Student("wang2",5,"f"));
        students.add(new Student("zh3",3,"f"));
        students.add(new Student("li4",5,"f"));
        Optional<Student> optionalStudent = students.stream().filter(student -> student.getName().length() == 3).findAny();
        System.out.println(optionalStudent.toString());

    }
}

5.2基于findFirst()查找元素

findFirst使用原理与findAny类似,只是它无论串行流还是并行流都会返回第一个元素

 

6、归约

到现在截止,对于流的终端操作,我们返回的有boolean、Optional和List。但是在集合操作中,我们经常会涉及 对元素进行统计计算之类的操作,如求和、求大值、小值等,从而返回不同的数据结果。

6.1基于reduce()进行累积求和

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

/**
 * @author rx
 * @date 2022/6/3 13:34
 */
public class StreamDemo10 {
    public static void main(String[] args) {
        List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
        Integer reduce = list.stream().reduce(0, (x1, x2) -> x1 + x2);
        System.out.println(reduce);
    }
}

  在上述代码中,在reduce里的第一个参数声明为初始值,第二个参数接收一个lambda表达式,代表当前流中的两 个元素,它会反复相加每一个元素,直到流被归约成一个终结果

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

/**
 * @author rx
 * @date 2022/6/3 13:34
 */
public class StreamDemo11 {
    public static void main(String[] args) {
        List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
        Optional<Integer> reduce = list.stream().reduce(Integer::sum);
        if (reduce.isPresent()){
            System.out.println(reduce);
        }else
            System.out.println("data is error");
    }
}

6.2 获取流中的最大值最小值

public class StreamDemo12 {
    public static void main(String[] args) {
​
        List<Integer> integers = Arrays.asList(1, 2, 3, 4, 4, 5, 5, 6, 7, 8, 2, 2, 2, 2);
​
        /**
         * 获取集合中的最大值
         */
        //方法一
        Optional<Integer> max1 = integers.stream().reduce(Integer::max);
        if(max1.isPresent()){
            System.out.println(max1);
        }
        //方法二
        Optional<Integer> max2 = integers.stream().max(Integer::compareTo);
        if(max2.isPresent()){
            System.out.println(max2);
        }
​
        /**
         * 获取集合中的最小值
         */
        //方法一 
        Optional<Integer> min1 = integers.stream().reduce(Integer::min);
        if(min1.isPresent()){
            System.out.println(min1);
        }
​
        //方法二
        Optional<Integer> min2 = integers.stream().min(Integer::compareTo);
        if(min2.isPresent()){
            System.out.println(min2);
        }
    }
} 

7、收集器

通过使用收集器,可以让代码更加方便的进行简化与重用。其内部主要核心是通过Collectors完成更加复杂的计算 转换,从而获取到终结果。并且Collectors内部提供了非常多的常用静态方法,直接拿来就可以了。比方说: toList。

import jdk.nashorn.internal.ir.IfNode;

import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @author rx
 * @date 2022/6/1 17:18
 */
public class StreamDemo13 {
    public static void main(String[] args) {
        List<Student> students = new ArrayList<>();
        students.add(new Student("wang2", 5, "f"));
        students.add(new Student("zh3", 3, "f"));
        students.add(new Student("yx", 88, "f"));
        //计算个数,方法一
        Long collect = students.stream().collect(Collectors.counting());
        System.out.println(collect);
        //计算个数,方法二
        long count = students.stream().count();
        System.out.println(count);
        //通过maxBy求最大值,方法一
        Optional<Student> optional1 = students.stream().collect(Collectors.maxBy(Comparator.comparing(student -> student.getAge())));
        if (optional1.isPresent()) {
            System.out.println(optional1);
        }
//通过maxBy求最大值,方法二
        Optional<Student> max = students.stream().max(Comparator.comparing(Student::getAge));
        if (max.isPresent()) {
            System.out.println(max);
        }
//通过summingInt()进行数据汇总
        Integer collect1 = students.stream().collect(Collectors.summingInt(Student::getAge));
        System.out.println(collect1);
        //通过averagingInt()获取平均值
        Double collect3 = students.stream().collect(Collectors.averagingInt(student -> student.getAge()));
        System.out.println(collect3);
        //通过joining方法进行数据拼接
        String collect2 = students.stream().map(Student::getName).collect(Collectors.joining());
        System.out.println(collect2);
        //复杂结果的返回
        IntSummaryStatistics collect4 = students.stream().collect(Collectors.summarizingInt(Student::getAge));
        collect4.getSum();
        collect4.getMax();
        collect4.getCount();
        collect4.getAverage();
        collect4.getMin();
    }
}

8、分组

 

在数据库操作中,经常会通过group by对查询结果进行分组。同时在日常开发中,也经常会涉及到这一类操作, 如通过性别对学生集合进行分组。如果通过普通编码的方式需要编写大量代码且可读性不好。

对于这个问题的解决,java8也提供了简化书写的方式。通过 Collectors。groupingBy()即可。

public class StreamDemo14 {
    public static void main(String[] args) {
        List<Student> students = new ArrayList<>();
        students.add(new Student("wang2", 5, "m"));
        students.add(new Student("zh3", 3, "f"));
        students.add(new Student("yx", 88, "m"));
        students.add(new Student("sd", 88, "f"));
        students.add(new Student("cd", 88, "m"));
        Map<String, List<Student>> collect = students.stream().collect(Collectors.groupingBy(Student::getGender));
        System.out.println(collect);
       //结果: {f=[Student{name='zh3', age=3, gender='f'}, Student{name='sd', age=88, gender='f'}], m=[Student{name='wang2', age=5, gender='m'}, Student{name='yx', age=88, gender='m'}, Student{name='cd', age=88, gender='m'}]}
    }
}

  8.1多级分组

public class StreamDemo15 {
    public static void main(String[] args) {
        List<Student> students = new ArrayList<>();
        students.add(new Student("wang2", 5, "m"));
        students.add(new Student("zh3", 3, "f"));
        students.add(new Student("yx", 88, "m"));
        students.add(new Student("sd", 88, "f"));
        students.add(new Student("cd", 88, "m"));
        Map<String, Map<String, List<Student>>> collect = students.stream().collect(Collectors.groupingBy(Student::getGender, Collectors.groupingBy(Student::getGender)));
        System.out.println(collect);
       //结果:{f={f=[Student{name='zh3', age=3, gender='f'}, Student{name='sd', age=88, gender='f'}]}, m={m=[Student{name='wang2', age=5, gender='m'}, Student{name='yx', age=88, gender='m'}, Student{name='cd', age=88, gender='m'}]}}
    }
}

  

posted @ 2022-06-03 14:26  luorx  阅读(781)  评论(0)    收藏  举报