Java8新特性——Stream API
发布日期:2021-05-08 01:13:48 浏览次数:21 分类:精选文章

本文共 14375 字,大约阅读时间需要 47 分钟。

1、stream API——相识

       Stream是元素的集合,这点让Stream看起来有些类似Iterator;可以支持顺序和并行的对原Stream进行汇聚的操作。

       大家可以把Stream当成一个高级版本的Iterator。原始版本的Iterator,用户只能一个一个的遍历元素并对其执行某些操作;高版本的Stream,用户只要给出需要对其包含的元素执行什么操作,比如:“过滤掉长度大于10的字符串”、“获取每个字符串的首字母”等,这些操作如何应用到每个元素上,就给Stream就好了!

2、Stream API——创建、中间操作、终止操作(终端操作)

        创建:一个数据源(如:集合、数组),获取一个流。

//    创建Stream    @Test    public void fun1(){//      1.可以通过Collection系列集合提供的stream()串行流或parallelStream()并行流        List
list = new ArrayList<>(); Stream
stream1 = list.stream();// 2.通过Arrays中的静态方法stream()获得数组流 Employee [] emps = new Employee[10]; Stream
stream2 = Arrays.stream(emps);// 3.通过Stream类中的静态方法of() Stream
stream3 = Stream.of("aa","bb","cc");// 4.创建无限流// (1)迭代 Stream
stream4 = Stream.iterate(0, (x) -> x + 2); stream4.limit(10) .forEach(System.out::println);// (2)生成 Stream.generate(() -> Math.random()) .limit(5) .forEach(System.out::println); }

       中间操作:一个中间操作链,对数据源的数据进行处理。

                 (1)、筛选与切片

//    中间操作    /*     筛选和切片        filter——接收Lambda,从流中排除某些元素。        limit——截断流,使其元素不超过给定数量。        skip(n)——跳过元素,返回一个扔掉了前n个元素的流,若流中元素不足n个时,则返回一个空流,与limit互补        distinct——筛选,通过流所生成元素的HashCode()和equals()去除重复元素    */List
employees = Arrays.asList( new Employee("张三",18,9999.99), new Employee("张三",18,9999.99), new Employee("张三",18,9999.99), new Employee("张三",18,9999.99), new Employee("张三",18,9999.99), new Employee("张三",18,9999.99), new Employee("李四",18,8888.88), new Employee("王五",100,1.11), new Employee("赵六",80,2.22), new Employee("田七",20,9898.98) ); /*内部迭代:迭代操作由Stream API完成*/ @Test public void fun2(){// 中间操作:不会执行任何操作 Stream
stream = employees.stream() .filter((e) -> { System.out.println("Stream API的中间操作"); System.out.println("没有终止操作的话,中间操作不执行。"); return e.getAge() > 35; });// 终止操作:一次性执行全部内容,即惰性求值 stream.forEach(System.out::println); } /*外部迭代*/ @Test public void fun3(){ Iterator
iterator = employees.iterator(); while (iterator.hasNext()){ System.out.println(iterator.next()); } } @Test public void fun4(){ employees.stream() .filter((e) -> { System.out.println("短路!"); //&& || return e.getSalary() >5000; }) .limit(2) .forEach(System.out::println); } @Test public void fun5(){ employees.stream() .filter((e) -> e.getSalary()>5000) .skip(2) .forEach(System.out::println); } @Test public void fun6(){ employees.stream() .filter((e) -> e.getSalary()>5000) .distinct() .forEach(System.out::println); }
package Lambda.LambdaCase;public class Employee {    private String name;    private Integer age;    private Double salary;    public Employee() {    }    public Employee(Integer age) {        this.name = name;    }    public Employee(String name, Integer age) {        this.name = name;        this.age = age;    }    public Employee(String name, Integer age, Double salary) {        this.name = name;        this.age = age;        this.salary = salary;    }    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    public Integer getAge() {        return age;    }    public void setAge(Integer age) {        this.age = age;    }    public Double getSalary() {        return salary;    }    public void setSalary(Double salary) {        this.salary = salary;    }    @Override    public boolean equals(Object o) {        if (this == o) return true;        if (o == null || getClass() != o.getClass()) return false;        Employee employee = (Employee) o;        if (!name.equals(employee.name)) return false;        if (!age.equals(employee.age)) return false;        return salary.equals(employee.salary);    }    @Override    public int hashCode() {        int result = name.hashCode();        result = 31 * result + age.hashCode();        result = 31 * result + salary.hashCode();        return result;    }    @Override    public String toString() {        return "Employee{" +                "name='" + name + '\'' +                ", age=" + age +                ", salary=" + salary +                '}';    }}

       (2).映射

/*      映射        map——接收lambda,将元素转换成其他形式或提取信息。               接收一个函数作为参数,该函数会应用到每个元素上,并将其映射成一个新的元素。        flagMap——接收一个函数作为参数,将流中的每个值都换成另一个流,然后把所有流连接成一个流。    */    @Test    public void fun7(){        List
list = Arrays.asList("aaa","bbb","ccc","ddd","eee"); list.stream() .map((str) -> str.toUpperCase()) .forEach(System.out::println); System.out.println("------------我是分割线-------------"); employees.stream() .map(Employee::getName) .forEach(System.out::println); System.out.println("------------我是分割线-------------"); Stream
> stream = list.stream() .map(GetUnlimitedFlow::filterCharacter);//{ {a,a,a},{b,b,b}} stream.forEach((sm) ->{ sm.forEach(System.out::println); }); System.out.println("------------我是分割线-------------"); Stream
stream1 = list.stream() .flatMap(GetUnlimitedFlow::filterCharacter);//{a,a,a,b,b,b} stream1.forEach(System.out::println); } /*解析字符串,将字符串中的字符一个个打印出来*/ public static Stream
filterCharacter(String str){//add(Object obj) addAll(Collection coll) ArrayList
list = new ArrayList<>(); for (Character ch:str.toCharArray()) { list.add(ch); } return list.stream(); } @Test public void fun8(){ List
list = Arrays.asList("aaa", "bbb", "ccc", "ddd", "eee"); ArrayList list1 = new ArrayList(); list1.add(11); list1.add(33);// list1.add(list);// System.out.println(list1); list1.addAll(list); System.out.println(list1); }

    (3).排序

/*      排序         sorted()——自然排序(Comparable)         sorted(Comparator com)——定制排序(Comparater)    */    @Test    public void fun9(){        List
list = Arrays.asList("bbb", "ddd", "aaa", "eee", "ccc"); list.stream() .sorted() .forEach(System.out::println); System.out.println("------------我是分割线-------------"); employees.stream() .sorted((e1,e2) -> { if (e1.getAge().equals(e2.getAge())){ return e1.getName().compareTo(e2.getName()); }else { return -e1.getAge().compareTo(e2.getAge()); } }).forEach(System.out::println); }

       终止操作:一个终止操作,执行中间操作链,并产生结果。

     查找与匹配

    

List
employees1 = Arrays.asList( new Employee("张三",18,9999.99, Employee.Status.BUSY), new Employee("李四",18,8888.88, Employee.Status.FREE), new Employee("王五",100,1.11, Employee.Status.VOCATION), new Employee("赵六",80,2.22, Employee.Status.FREE), new Employee("田七",20,9898.98, Employee.Status.BUSY) ); /* 查找与匹配 allMatch——检查是否匹配所有元素 anyMatch——检查是否至少匹配一个元素 noneMatch——检查是否没有匹配所有元素 findFirst——返回第一个元素 findAny——返回当前流中的任意元素 count——返回流中元素的总个数 max——返回流中最大值 min——返回流中最小值 */ @Test public void fun10(){ boolean b1 = employees1.stream() .allMatch((e) -> e.getStatus().equals(Employee.Status.BUSY)); System.out.println(b1); boolean b2 = employees1.stream() .anyMatch((e) -> e.getStatus().equals(Employee.Status.BUSY)); System.out.println(b2); boolean b3 = employees1.stream() .noneMatch((e) -> e.getStatus().equals(Employee.Status.BUSY)); System.out.println(b3); Optional
op = employees1.stream() .sorted((e1, e2) -> Double.compare(e1.getSalary(), e2.getSalary())) .findFirst(); System.out.println(op.get()); Optional
any = employees1.stream() .filter((e) -> e.getStatus().equals(Employee.Status.BUSY)) .findAny(); System.out.println(any.get()); } @Test public void fun11() { long count = employees1.stream() .count(); System.out.println(count); Optional
max = employees1.stream() .max((e1, e2) -> Double.compare(e1.getSalary(), e2.getSalary())); System.out.println(max.get()); Optional
min = employees1.stream() .map(Employee::getSalary) .min(Double::compare); System.out.println(min.get()); }
归约
/*      归约        reduce(T identity,BinaryOperator)/reduce(BinaryOperator)            ——可以将流中元素反复结合起来,得到一个值    */    @Test    public void fun12(){        List
list = Arrays.asList(1,2,3,4,5,6,7,8,9,10); Integer sum = list.stream() .reduce(0,(x,y) -> x+y); System.out.println(sum); System.out.println("------------我是分割线-------------"); Optional
reduce = employees1.stream() .map(Employee::getSalary) .reduce(Double::sum); System.out.println(reduce.get()); }

    收集

/*     收集:        collect——将流转换为其他形式,接收一个Collector接口的实现,                   用于给Stream中元素做汇总的方法。    */    @Test    public void fun13(){        List
list = employees1.stream() .map(Employee::getName) .collect(Collectors.toList()); list.forEach(System.out::println); System.out.println("------------我是分割线-------------"); Set
set = employees1.stream() .map(Employee::getName) .collect(Collectors.toSet()); set.forEach(System.out::println); System.out.println("------------我是分割线-------------"); HashSet
hashSet = employees1.stream() .map(Employee::getSalary) .collect(Collectors.toCollection(HashSet::new)); hashSet.forEach(System.out::println); } @Test public void fun14(){// 总数 Long count = employees1.stream() .collect(Collectors.counting()); System.out.println(count); System.out.println("------------我是分割线-------------");// 平均值 Double avg = employees1.stream() .collect(Collectors.averagingDouble(Employee::getSalary)); System.out.println(avg); System.out.println("------------我是分割线-------------");// 总和 Double sum = employees1.stream() .collect(Collectors.summingDouble(Employee::getSalary)); System.out.println(sum); System.out.println("------------我是分割线-------------");// 最大值 Optional
max = employees1.stream() .collect(Collectors.maxBy((e1, e2) -> Double.compare(e1.getSalary(), e2.getSalary()))); System.out.println(max.get()); System.out.println("------------我是分割线-------------");// 最小值 Optional
min = employees1.stream() .map(Employee::getSalary) .collect(Collectors.minBy(Double::compare)); System.out.println(min.get()); }

   分组和多级分组

@Test    public void fun15(){//      分组        Map
> map = employees1.stream() .collect(Collectors.groupingBy(Employee::getStatus)); System.out.println(map); }// 多级分组 @Test public void fun16(){ Map
>> mapMap = employees1.stream() .collect(Collectors.groupingBy(Employee::getStatus, Collectors.groupingBy((e) -> { if (e.getAge() < 5) { return "青年"; } else if (e.getAge() < 10) { return "中年"; } else { return "老年"; } }))); System.out.println(mapMap); }

  分区

//    分区    @Test    public void fun17(){        Map
> partition = employees1.stream() .collect(Collectors.partitioningBy((e) -> e.getSalary() > 8000)); System.out.println(partition); }

  汇总统计

//  汇总统计    @Test    public void fun18(){        DoubleSummaryStatistics summary = employees1.stream()                                                     .collect(Collectors.summarizingDouble(Employee::getSalary));        System.out.println(summary);        System.out.println(summary.getAverage());        System.out.println(summary.getCount());        System.out.println(summary.getMax());        System.out.println(summary.getMin());        System.out.println(summary.getSum());    }

  字符串拼接

//  字符串拼接    @Test    public void fun19(){        String join = employees1.stream()                .map(Employee::getName)                .collect(Collectors.joining(",","===","==="));        System.out.println(join);    }

package Steam;import Lambda.LambdaCase.Employee;import org.junit.Test;import java.util.Arrays;import java.util.List;import java.util.Optional;public class TestStreamAPI {    /*      1、给定一个数字列表,如何返回一个由每个数的平方构成的列表呢?         给定【1,2,3,4,5】,应该返回【1,4,9,16,25】    */    @Test    public void fun1(){        Integer [] arr = new Integer[]{1,2,3,4,5};        Arrays.stream(arr)              .map((x) -> x*x)              .forEach(System.out::println);    }    /*      2、怎样用map和reduce方法数一数流中有多少个Employee?    */    List
employees = Arrays.asList( new Employee("张三",18,9999.99, Employee.Status.BUSY), new Employee("李四",18,8888.88, Employee.Status.FREE), new Employee("王五",100,1.11, Employee.Status.VOCATION), new Employee("赵六",80,2.22, Employee.Status.FREE), new Employee("田七",20,9898.98, Employee.Status.BUSY) ); @Test public void fun2(){ Optional
sum = employees.stream() .map((e) -> 1) .reduce(Integer::sum); System.out.println(sum.get()); }}

 

      

        

上一篇:2020 BAT大厂数据分析面试经验:“高频面经”之数据分析篇
下一篇:2020 BAT大厂数据开发面试经验:“高频面经”之大数据研发篇

发表评论

最新留言

路过,博主的博客真漂亮。。
[***.116.15.85]2025年04月11日 23时10分20秒