zoukankan      html  css  js  c++  java
  • Java8(四) StreamAPI

    Stream API

    使用一种类似于SQL语句从数据库查询数据的直观方式对Java集合进行运算和表达。

    将要处理的元素集合看作一种流, 流在管道中传输,我们可以在管道的节点上进行处理, 比如筛选, 排序,聚合等。

    Stream的三个操作步骤为:

    • 创建Stream:从一个数据源,如集合、数组中获取流。
    • 中间操作:对数据源的数据进行操作。
    • 终止操作:产生结果。

    Stream的操作符大体上分为两种:中间操作符终止操作符

    1 中间操作符

    中间操作符在执行处理程序后,数据流依然可以传递给下一级的操作符。

    map
    <R> Stream<R> map(Function<? super T, ? extends R> mapper);
    //接收一个函数作为参数,该函数会被应用到每个元素上,并将其映射成一个新的元素。
    
    public class Person {
    
        public String name;
        public int age;
    
        public Person(String name) {
            this.name = name;
        }
        
        //getter方法
    }
    
    //提取对象属性
    Person p1 = new Person("张三");
    Person p2 = new Person("李四");
    List<Person> personList = new ArrayList<>();
    personList.add(p1);
    personList.add(p2);
    
    List<String> collect = personList.stream().map(Person::getName).collect(Collectors.toList());
    collect.forEach(System.out :: println);
    
    flatmap
    <R> Stream<R> flatMap(Function<? super T, ? extends Stream<? extends R>> mapper);
    
    public class Grade {
    
        private String name;
        private List<Student> studentList = new ArrayList<>();
    
        public Grade(String name) {
            this.name = name;
        }
    
        public void addStudent(Student student) {
            studentList.add(student);
        }
    }
    
    public class Student {
    
        public String name;
        public int age;
    
        public Student(String name) {
            this.name = name;
        }
    
        public Student(String name, int age) {
            this.name = name;
            this.age = age;
        }
    
        public String getName() {
            return name;
        }
    
        public int getAge() {
            return age;
        }
    }
    
    Student s1 = new Student("张三");
    Student s2 = new Student("李四");
    
    Grade grade1 = new Grade("一班");
    grade1.addStudent(s1);
    
    Grade grade2 = new Grade("二班");
    grade2.addStudent(s2);
    
    List<Grade> list = new ArrayList<>();
    list.add(grade1);
    list.add(grade2);
    
    list.stream().flatMap(x -> x.get)
    
    limit
    Stream<T> limit(long maxSize);
    //设限、截断
    
    List<Integer> list = Arrays.asList(1, 3, 5, 7, 9, 11);
    Stream<Integer> stream = list.stream().limit(2);
    stream.forEach(System.out :: println);
    
    distinct
    Stream<T> distinct();
    //去重,通过元素的hashCode()和equals()去除重复元素
    
    List<Integer> list = Arrays.asList(1, 1, 3, 5, 7, 9, 11);
    Stream<Integer> stream3 = list.stream().distinct();
    stream3.forEach(System.out :: println);
    

    自定义的实体类使用distinct去重时,一定要先重写hashCode()和equals()方法

    filter
    Stream<T> filter(Predicate<? super T> predicate);
    //过滤器
    
    List<Integer> list = Arrays.asList(1, 3, 5, 7, 9, 11);
    Stream<Integer> stream = list.stream().filter(x -> x > 5);
    stream.forEach(System.out :: println);
    
    peek
    Stream<T> peek(Consumer<? super T> action);
    
    skip
    Stream<T> skip(long n);
    //跳过,与limit互补,跳过元素返回一个舍弃了前n个元素的流,若流中元素不满足n个,则返回一个空流
    
    List<Integer> list = Arrays.asList(1, 3, 5, 7, 9, 11);
    Stream<Integer> stream = list.stream().skip(2);
    stream.forEach(System.out :: println);
    
    sorted
    Stream<T> sorted();
    Stream<T> sorted(Comparator<? super T> comparator);
    //排序
    
    list.stream().sorted() 
    list.stream().sorted(Comparator.reverseOrder()) 
    list.stream().sorted(Comparator.comparing(Student::getAge)) 
    list.stream().sorted(Comparator.comparing(Student::getAge).reversed()) 
    //或者自己实现Comparator逻辑
    

    2 终止操作符

    终止操作符就是用来对数据进行收集或者消费的,数据到了终止操作这里就不会向下流动了,终止操作符只能使用一次。

    collect收集操作
    <R> R collect(Supplier<R> supplier, BiConsumer<R, ? super T> accumulator, BiConsumer<R, R> combiner);
    <R, A> R collect(Collector<? super T, A, R> collector);
    

    用 Collectors 来进行 reduction 操作

    java.util.stream.Collectors 类的主要作用就是辅助进行各类有用的reduction操作,例如转变输出为Collection, 把Stream元素进行归组等。

    count统计操作
    long count();
    //返回流中元素的总数
    
    find查找操作
    Optional<T> findFirst();
    Optional<T> findAny();
    //查找
    
    match匹配操作
    boolean anyMatch(Predicate<? super T> predicate);
    boolean allMatch(Predicate<? super T> predicate);
    boolean noneMatch(Predicate<? super T> predicate);
    
    Max/Min最值操作
    Optional<T> max(Comparator<? super T> comparator);
    Optional<T> min(Comparator<? super T> comparator);
    
    reduce规约操作
    T reduce(T identity, BinaryOperator<T> accumulator);
    Optional<T> reduce(BinaryOperator<T> accumulator);
    <U> U reduce(U identity, BiFunction<U, ? super T, U> accumulator, BinaryOperator<U> combiner);
    
    forEach遍历操作
    void forEach(Consumer<? super T> action);
    void forEachOrdered(Consumer<? super T> action);
    
    toArray数组操作
    Object[] toArray();
    <A> A[] toArray(IntFunction<A[]> generator);
    

    3 流的构建

    数组创建
    String[] arr = { "a", "b", "c"};
    Stream<String> stream1 = Stream.of(arr);
    Stream<String> stream2 = Arrays.stream(arr);
    
    Collections创建
    List<String> list = new ArrayList<String>();
    list.add("a");
    list.add("b");
    list.add("c");
    Stream<String> stream = list.stream();
    
    Stream.generate()
    Stream.generate(Math::random).limit(5)
    
    Stream.iterate()
    Stream.iterate(0, n -> n + 2).limit(10)
    
  • 相关阅读:
    什么叫继承?
    两类交换元素使序列有序 求最少交换次数的题
    如何理解汉诺塔
    求给出第 K个 N位二进制数,该二进制数不得有相邻的“1”
    7/26 CSU-ACM2018暑期训练3-递归&递推-选讲
    平面分割
    递推算法之平面分割问题总结
    UTC时间
    7/25 CSU-ACM2018暑假集训比赛1
    洛谷 P1824 进击的奶牛【二分答案/类似青蛙过河】
  • 原文地址:https://www.cnblogs.com/lyldelove/p/13357991.html
Copyright © 2011-2022 走看看