资讯专栏INFORMATION COLUMN

Java8中创建Stream 流的四种方式以及 Stream 中间操作

0xE7A38A / 1136人阅读

摘要:一创建里流的四种方式第一种通过得方法串行流或者方法并行流创建。终止操作时一次性全部处理,称为延迟加载筛选切片过滤中建操作。终止操作只有执行终止操作才会执行全部。即延迟加载结果中建操作。截断流,使其元素不超过给定数量。返回流中最大值。

Stream api
**Stream api 是java8 中提供的对集合处理的api , 对数据进行一系列的中间操作,元数据不会发生改变
                集合讲的是数据, 流 讲的是计算(用于操作数据源,集合,数组)所生成的元素序列。**
                
         Stream API位于 java.util.stream.* 包下。

1 Stream 自己不会存储元素

                   2 Stream 不会改变源对象。相反,他们会返回一个持有结果的性Sstream 。
                  3 Stream 操作是延迟执行的。这以为这他们会等到需要结果的时候才执行(延迟加载)。
一 创建里Stream 流的四种方式

### 1 第一种 通过Collection得Stream()方法(串行流)或者 parallelStream()方法(并行流)创建Stream。

         List list = Arrays.asList("1","2","3","4","0","222","33");
        Stream stream = list.stream();
         Stream stream1 = list.parallelStream();

### 2 通过Arrays中得静态方法stream()获取数组流

        IntStream stream = Arrays.stream(new int[]{1,2,3});

### 3 通过Stream类中得 of()静态方法获取流

       Stream stream = Stream.of("a","b","c");

### 4 创建无限流(迭代、生成)

//迭代(需要传入一个种子,也就是起始值,然后传入一个一元操作)
     Stream stream1 = Stream.iterate(2, (x) -> x * 2);

     //生成(无限产生对象)
     Stream stream2 = Stream.generate(() -> Math.random());
       
二 Stream 中间操作
多个中间操作可以连接起来形成一个流水线,除非流水线终止操作,否则中间操作不会执行任何处理。
终止操作时一次性全部处理,称为“延迟加载”
1 筛选切片
1 过滤
List list = Arrays.asList("1","2","3","4","0","222","33");
Stream stream = list.stream().filter((x) -> {
            System.out.println(" api  中建操作。");
            return x.equals("3");
        });
        //终止操作:只有执行终止操作才会执行全部。即:延迟加载
        stream.forEach(System.out::println);

结果

 api  中建操作。
 api  中建操作。
 api  中建操作。
3
 api  中建操作。
 api  中建操作。
 api  中建操作。
 api  中建操作。
2 limit() 截断流,使其元素不超过给定数量。
List list = Arrays.asList("1","2","3","4","0","222","33","3","3");
 Stream stream = list.stream().filter((x) -> {
            System.out.println(" api  中建操作。");
            return x.equals("3");
        });
        //取两个 , 可以配合其他得中间操作,并截断流,取到相应的元素个数,这不会往下执行,可以提高效率
        stream.limit(2).forEach(System.out::println);
3 skip(n) 跳过元素

skip(n),返回一个扔掉了前n个元素的流。若流中元素不足n个,则返回一个空,与limit(n)互补。

List list = Arrays.asList("1","2","3","4","0","222","33","3","3");
        Stream stream = list.stream().filter((x) -> {
            System.out.println(" api  中建操作。");
            return x.equals("3");
        });
        //skip(n),返回一个扔掉了前n个元素的流。若流中元素不足n个,则返回一个空,与limit(n)互补。
        stream.skip(3).limit(1).forEach(System.out::println);
4 筛选

    distinct 通过流所生成元素的hashCode()和equals()去除重复元素

List list = Arrays.asList("1","2","3","4","0","222","33","3","3");
 Stream stream = list.stream();
        stream.distinct().forEach(System.out::println);
1
2
3
4
0
222
33
5 映射

map - 接受lambda 将元素转换为其他形式或提取信息。

接受一个函数作为参数,该函数会被应用到每个元素上,并将其映射成一个新元素



flatMap 接受一个函数作为参数,将流中的每个值都转成另一个流,然后把所有流连成一个流。

List stuList = Arrays.asList(new Stu("a",1),new Stu("ab",3),new Stu("c",11),new Stu("f",12));
 
   Stream stream = stuList.stream();
        //去除list中所有的年龄
        stream.map(Stu::getAge).forEach(System.out::println);
        //把所有年龄再返回一个集合
        List collect = stream.map(Stu::getAge).collect(Collectors.toList());

        stream.flatMap(stu -> test1.filterCharacter(stu.getName())).forEach(System.out::println);
6 排序

sorted有两种方法,一种是不传任何参数,叫自然排序,还有一种需要传Comparator 接口参数,叫做定制排序。

 //自然排序
        List collect = list.stream().sorted().collect(Collectors.toList());
        
        List collect2 = list.stream().sorted((o1, o2) -> {
            if(o1.length()>o2.length()){
                return 1;
            }else 
            if(o1.length()
三  Stream 终止操作

实体类

public class Person {
    String name ;
    String sex ;
    int age;
    Status statusEnum;

    public Person(String name, String sex, int age, Status statusEnum) {
        this.name = name;
        this.sex = sex;
        this.age = age;
        this.statusEnum = statusEnum;
    }

    public String getName() {
        return name;
    }

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

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public int getAge() {
        return age;
    }

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

    public Status getStatusEnum() {
        return statusEnum;
    }

    public void setStatusEnum(Status statusEnum) {
        this.statusEnum = statusEnum;

}

    @Override
    public String toString() {
        return "Person{" +
                "name="" + name + """ +
                ", sex="" + sex + """ +
                ", age=" + age +
                ", statusEnum=" + statusEnum +
                "}";
    }
}
操作
 List persons = Arrays.asList(
                          new Person("张三", "男", 76, Status.FREE),
              new Person("李四", "女", 12, Status.BUSY),
               new Person("王五", "男", 35, Status.BUSY),
               new Person("赵六", "男", 3, Status.FREE),
               new Person("钱七", "男", 56, Status.BUSY),
               new Person("翠花", "女", 34, Status.VOCATION),
               new Person("翠花", "女", 34, Status.FREE),
               new Person("翠花", "女", 34, Status.VOCATION)
              );
1 查找与匹配

##### 1 allMatch —— 检查是否匹配所有元素。

    public void test1(){
        boolean allMatch = persons.stream().allMatch((x) -> {
            return x.getStatusEnum().equals(Status.FREE);
        });

        System.out.println(allMatch);
    }
2 anyMatch —— 检查是否至少匹配一个元素。
    public void test2(){
        boolean allMatch = persons.stream().anyMatch((x) -> {
            return x.getStatusEnum().equals(Status.FREE);
        });

        System.out.println(allMatch);
    }
3 noneMatch —— 检查是否没有匹配所有元素。
  检查 所有的是否都是 FREE  ----- 结果是false
    public void test3(){
        boolean allMatch = persons.stream().noneMatch((x) -> {
            return x.getStatusEnum().equals(Status.FREE);
        });

        System.out.println(allMatch);
    }
4 findFirst —— 返回第一个元素。
 public void test4(){
      Optional first = persons.stream().findFirst();

      System.out.println(first.get());
  }

##### 5 findAny —— 返回当前流中任意元素。

public void test5(){
     Optional first = persons.stream().findAny();
     //first.orElse(new Person());  如果没空 可以穿一个新的对象去代替它
     System.out.println(first.get());
 }

##### 6 count —— 返回流中元素总个数。

  public void test6(){
      long first = persons.stream().count();
      System.out.println(first);
  }

##### 7 max —— 返回流中最大值。

public void test7(){
     Optional person = persons.stream().max((x,y) ->  Integer.compare(x.age, y.age));
     System.out.println(person.get());
 }

##### 8 min —— 返回流中最小值。

public void test8(){
      Optional person = persons.stream().min((x,y) ->  Integer.compare(x.age, y.age));
      System.out.println(person.get());
  }
2 归约 : 可以将流中元素反复结合在一起,得到一个值
1 reduce(T identitty,BinaryOperator)首先,需要传一个起始值,然后,传入的是一个二元运算。
  public void test9(){
       List list = Arrays.asList(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
               // identitty 起始值 0  然后与集合中的值进行 相应的运算,再次赋值给 identity 然后 在进行运算。
                Integer sum = list.stream().reduce(0, (x, y) -> x + y);
       System.out.println(sum);
   }

##### 2 reduce(BinaryOperator)此方法相对于上面方法来说,没有起始值,则有可能结果为空,所以返回的值会被封装到Optional中。

map和reduce的连接通常称为map-reduce模式,因Google用它来进行网络搜索而出名。

用map 来提取 对象中某个属性,然后再用reduce 进行归约。
    public void test10() {
        Optional reduce = persons.stream().map(Person::getAge).reduce(Integer::sum);
        System.out.println(reduce.get());
    }
3 收集 : 收集collect(将流转换为其他形式。接收一个Collector接口得实现,用于给其他Stream中元素做汇总的方法)
 
       Collector接口中方法得实现决定了如何对流执行收集操作(如收集到List,Set,Map)。
       但是Collectors实用类提供了很多静态方法,可以方便地创建常见得收集器实例。
 
1 Collectors.toList() 将流转换成List
 public void test11() {
     List collect = persons.stream().collect(Collectors.toList());
     collect.forEach(System.out::println);
 }

###### 2 将流转换成HashSet

     public void test12() {
      //hashset会去重复
          Set collect = persons.stream().map(Person::getName).collect(Collectors.toSet());
          collect.forEach(System.out::println);
      }

###### 3 将流转换成其他集合

public void test13() {

      Set collect = persons.stream().map(Person::getAge).collect(Collectors.toCollection(LinkedHashSet::new));
      collect.forEach(System.out::println);
  }

##### 4 Collectors.counting() 元素个数

 public void test14() {

      Long collect = persons.stream().map(Person::getAge).collect(Collectors.counting());
      System.out.println(collect);
  }

##### 5 将流转换为其他形式 , 接受一个conllectors接口的实现,用于给Stream中元素做汇总的方法

public void test14s() {
        // 1 对元素进行汇总方法
        DoubleSummaryStatistics collect = persons.stream().collect(Collectors.summarizingDouble(Person::getAge));
        IntSummaryStatistics collect2 = persons.stream().collect(Collectors.summarizingInt(Person::getAge));
        System.out.println(collect.getMax());
        System.out.println(collect.getAverage());
        System.out.println(collect.getCount());
        System.out.println(collect.getMin());
        System.out.println(collect.getSum());

###### 2 讲元素转换为其他形式

       String collect1 = persons.stream().map(Person::getName).collect(Collectors.joining(",","头","尾"));
        String collect3 = persons.stream().map(Person::getName).collect(Collectors.joining());
        System.out.println(collect1); //头张三,李四,王五,赵六,钱七,翠花,翠花,翠花尾
        System.out.println(collect3); // 张三李四王五赵六钱七翠花翠花翠花
    }
    1. Collectors.averagingDouble()
    2  Collectors.averagingDouble()
    3 Collectors.averagingLong()

    平均数,这三个方法都可以求平均数,不同之处在于传入得参数类型不同,返回值都为Double
    public void test15() {

        Double s = persons.stream().collect(Collectors.averagingDouble(Person::getAge));
        System.out.println(s);
    }

##### 8 Collectors.maxBy() 求最大值

      public void test16() {

          Optional collect = persons.stream().collect(Collectors.maxBy((o1, o2) -> Integer.compare(o1.age, o2.age)));
          System.out.println(collect.get().age);
      }

##### 9 Collectors.minBy() 求最小值

 public void test17() {

     Optional collect = persons.stream().collect(Collectors.minBy((o1, o2) -> Integer.compare(o1.age, o2.age)));
     System.out.println(collect.get().age);
 }
10 Collectors.groupingBy()分组 ,返回一个map
按照 Status 分组
  public void test18() {

      Map> collect = persons.stream().collect(Collectors.groupingBy(Person::getStatusEnum));
      collect.forEach((status, people) -> {
          System.out.println(" status === " + status);
          people.forEach(System.out::println);
      });
  }

###### 11 多级分组

  Collectors.groupingBy()还可以实现多级分组
 public void test19() {

     Map>> collect = persons.stream().collect(Collectors.groupingBy(Person::getStatusEnum,Collectors.groupingBy(Person::getSex)));
     Map>> collect2 = persons.stream().collect(Collectors.groupingBy(Person::getStatusEnum,Collectors.groupingBy(
             e->{
                 if (e.getAge()>10){
                     return "小孩";
                 }else {
                     return "大人";
                 }
             }
     )));
     System.out.println(collect);
     System.out.println(collect2);
 }

##### 12 分区

Collectors.partitioningBy() 分区,参数中传一个函数,返回true,和false 分成两个区
public void test20() {
    年龄大于39的分区  不满足再的分区
      Map> collect = persons.stream().collect(Collectors.groupingBy(e -> e.getAge() > 30));

      System.out.println(collect);
  }

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/75143.html

相关文章

  • Java 8 数据流教程

    摘要:数据流教程原文译者飞龙协议这个示例驱动的教程是数据流的深入总结。但是的数据流是完全不同的东西。数据流是单体,并且在函数式编程中起到重要作用。列表上的所有流式操作请见数据流的。基本的数据流使用特殊的表达式,例如,而不是,而不是。 Java 8 数据流教程 原文:Java 8 Stream Tutorial 译者:飞龙 协议:CC BY-NC-SA 4.0 这个示例驱动的教程是J...

    XUI 评论0 收藏0
  • Java8实战》-第四章读书笔记(引入流Stream

    摘要:内部迭代与使用迭代器显式迭代的集合不同,流的迭代操作是在背后进行的。流只能遍历一次请注意,和迭代器类似,流只能遍历一次。 流(Stream) 流是什么 流是Java API的新成员,它允许你以声明性方式处理数据集合(通过查询语句来表达,而不是临时编写一个实现)。就现在来说,你可以把它们看成遍历数据集的高级迭代器。此外,流还可以透明地并行处理,你无需写任何多线程代码了!我会在后面的笔记中...

    _ivan 评论0 收藏0
  • Java8特性②Stream简介

    摘要:元素序列流也提供了一个接口,可以访问特定元素类型的一组有序值。因为集合是数据结构,所以它的主要目的是以特定的时间空间复杂度存储和访问元素如与。请注意,从有序集合生成流时会保留原有的顺序。由列表生成的流,其元素顺序与列表一致。 流是什么 流是Java API的新成员,它允许你以声明性方式处理数据集合(通过查询语句来表达,而不是临时编写一个实现)。可以把它们看成遍历数据集的高级迭代器。此外...

    EasonTyler 评论0 收藏0
  • 乐字节-Java8新特性之Stream流(上)

    摘要:需要注意的是很多流操作本身就会返回一个流,所以多个操作可以直接连接起来,如下图这样,操作可以进行链式调用,并且并行流还可以实现数据流并行处理操作。为集合创建并行流。 上一篇文章,小乐给大家介绍了《Java8新特性之方法引用》,下面接下来小乐将会给大家介绍Java8新特性之Stream,称之为流,本篇文章为上半部分。 1、什么是流? Java Se中对于流的操作有输入输出IO流,而Jav...

    dingda 评论0 收藏0
  • 乐字节-Java8核心特性实战之Stream(流)

    摘要:大家好,我是乐字节的小乐。需要注意的是很多流操作本身就会返回一个流,所以多个操作可以直接连接起来,如下图这样,操作可以进行链式调用,并且并行流还可以实现数据流并行处理操作。为集合创建并行流。 大家好,我是乐字节的小乐。说起流,我们会联想到手机、电脑组装流水线,物流仓库商品包装流水线等等,如果把手机 ,电脑,包裹看做最终结果的话,那么加工商品前的各种零部件就可以看做数据源,而中间一系列的...

    wenshi11019 评论0 收藏0

发表评论

0条评论

0xE7A38A

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<