Java8中 Stream创建流的四种方式、流的基本操作(流计算)

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<String> list = Arrays.asList("1","2","3","4","0","222","33");
        Stream<String> stream = list.stream();
         Stream<String> stream1 = list.parallelStream();

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

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

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


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

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

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

     //生成(无限产生对象)
     Stream<Double> stream2 = Stream.generate(() -> Math.random());
       

二 Stream 中间操作

多个中间操作可以连接起来形成一个流水线,除非流水线终止操作,否则中间操作不会执行任何处理。
终止操作时一次性全部处理,称为“延迟加载”

1 筛选切片

1 过滤
List<String> list = Arrays.asList("1","2","3","4","0","222","33");
Stream<String> 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<String> list = Arrays.asList("1","2","3","4","0","222","33","3","3");
 Stream<String> 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<String> list = Arrays.asList("1","2","3","4","0","222","33","3","3");
        Stream<String> 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<String> list = Arrays.asList("1","2","3","4","0","222","33","3","3");
 Stream<String> stream = list.stream();
        stream.distinct().forEach(System.out::println);
1
2
3
4
0
222
33

5 映射

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

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

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

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

6 排序

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

 //自然排序
        List<String> collect = list.stream().sorted().collect(Collectors.toList());
        
        List<String> collect2 = list.stream().sorted((o1, o2) -> {
            if(o1.length()>o2.length()){
                return 1;
            }else 
            if(o1.length()<o2.length()){
                return -1;
            }else {
                return 0;

            }
        }).collect(Collectors.toList());

三 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<Person> 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<Person> first = persons.stream().findFirst();

      System.out.println(first.get());
  }
5 findAny —— 返回当前流中任意元素。
public void test5(){
     Optional<Person> 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> person = persons.stream().max((x,y) ->  Integer.compare(x.age, y.age));
     System.out.println(person.get());
 }
8 min —— 返回流中最小值。
public void test8(){
      Optional<Person> 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<Integer> 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<Integer> 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<Person> collect = persons.stream().collect(Collectors.toList());
     collect.forEach(System.out::println);
 }
2 将流转换成HashSet
     public void test12() {
      //hashset会去重复
          Set<String> collect = persons.stream().map(Person::getName).collect(Collectors.toSet());
          collect.forEach(System.out::println);
      }
3 将流转换成其他集合
public void test13() {

      Set<Integer> 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<Person> 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<Person> 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<Status, List<Person>> 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<Status, Map<String, List<Person>>> collect = persons.stream().collect(Collectors.groupingBy(Person::getStatusEnum,Collectors.groupingBy(Person::getSex)));
     Map<Status, Map<String, List<Person>>> 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<Boolean, List<Person>> collect = persons.stream().collect(Collectors.groupingBy(e -> e.getAge() > 30));

      System.out.println(collect);
  }

更多请关注 微信公众号


微信公众号图片.png
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,723评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,003评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,512评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,825评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,874评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,841评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,812评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,582评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,033评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,309评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,450评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,158评论 5 341
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,789评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,409评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,609评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,440评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,357评论 2 352