Java8 学习笔记(二)——Stream流

1.简单使用

Arrays.asList(1, 4, 2, 3, 5, 6, 7, 9, 0, 8)
      .stream()
      .sorted()// 排序
      .filter(x -> x > 3)// 过滤
      .forEach(System.out::print);

运行结果:
4,5,6,7,8,9


  • Stream(流)和InputStream/OutputStream并没有关系
  • Stream提供了很多Lambda表达式方法
  • 重点在于对数组的操作

特点:

  1. Stream不存储数据
  2. Stream不会修改源数据,无论怎么操作源数据并不会改变
  3. Stream是单向的,不可以重复使用
  4. Stream的部分操作是延迟的
  • 只要Stream的方法返回的对象是Stream,这些方法就是延迟执行的方法
  • 延迟执行的方法,一定要等到一个迫切方法执行的时候,才会执行。一般在Stream流中,一个方法返回的不是Stream,基本就是迫切方法
  1. Stream可以执行并行操作

2.创建Stream

数组和集合创建Stream流方法不一样


2.1数组创建Stream

一般可以通过:Arrays.stream()Stream.of()

int [] ints = new int[]{1,3,4,2,5};
IntStream intStream= Arrays.stream(ints);
intStream.forEach(System.out::print);

运行结果:13425


注意:不能直接把简单数据类型的数组直接作为Stream.of()的参数

int [] ints = new int[]{1,3,4,2,5};
Stream<int[]>stream= Stream.of(ints);
stream.forEach(System.out::print);```
运行结果为:
`[I@1218025c`
***
```java
Stream<Integer>stream2 = Stream.of(1,3,4,2,5);
stream2.sorted().forEach(System.out::print);

运行结果为:
12345

Stream<Integer>IntStream不是同一个对象


2.2集合创建Stream

集合可以通过:集合对象.stream()

List<Integer>list = (List<Integer>) Arrays.asList(1,2,4,3,5);
Stream<Integer>stream = list.stream();

2.3创建并行Stream

通过集合对象.parallelStream()

List<Integer>list = (List<Integer>) Arrays.asList(1,2,4,3,5);
Stream<Integer>stream = list.parallelStream();

2.4 创建大量数据的Stream

  • 初始化一个无限重复字符串的Stream
Stream.generate(()->"Hello World!!!").forEach(System.out::println);

运行结果:
无限打印出Hello World!!!


  • 初始化一个有限的数据的Stream

可以通过limit()方法来限制创建数据的数量

Stream.generate(()->"Hello World !!!").limit(5).forEach(System.out::println);

运行结果:
打印出5个Hello World!!!


2.5创建一个规律数据的Stream

例如,创建一个从开始1到10的数列的Stream

Stream.iterate(1, x -> x +1).limit(10).forEach(System.out::print);

运行结果:12345678910

iterate()方法中,有两个参数,第一个为初始数据,第二个为一个Operator接口

Stream.iterate("a", UnaryOperator.identity()).limit(10).forEach(System.out::print);

运行结果:aaaaaaaaaa
UnaryOperator.identity()自己返回自己


3.Stream常见的操作

  • 过滤操作filter,distinct
  • 变换操作map,flatMap
  • 拆分合并流操作limit,skip,concat,peek
  • 排序操作sorted,unordered

操作符方法内往往需要一个函数式接口

Java8函数式接口

3.1过滤操作

  • filter
    例:找出所有开头为大写字母的字符串
Arrays.asList("Abc","Bc","ac","op","IQ")
        .stream()
        .filter(s->Character.isUpperCase(s.charAt(0)))
        .forEach(System.out::println);

运行结果:
Abc Bc IQ

  • distinct去除重复元素
Arrays.asList("a","c","ac","c","a","b")
        .stream()
        .distinct()
        .forEach(System.out::println);

运行结果:
a c ac b


3.2变换操作

  • map

把一种类型的Stream变为另一种类型的Stream,map方法内需要一个Function接口,Function<? super String, ? extends String> mapper

例:将字符串全部变为大写

Arrays.asList("hdfa","adfc","aedc","yui")
      .stream()
      .map(s->s.toUpperCase()+" ,")
      .forEach(System.out::print);

运行结果:
HDFA ,ADFC ,AEDC ,YUI ,

  • flatMap

flatMap方法也需要Function接口,只是Function接口的泛型不同,Function<? super T, ? extends Stream<? extends R>> mapper,返回的是Stream对象

private static void flatMapStream() {
    String [] strs1 = {"a","b","c"};
    String [] strs2 = {"d","e","f"};
    String [] strs3 = {"a","g","h"};
    Arrays.asList(strs1,strs2,strs3)
          .stream()
          .flatMap(str -> Stream.of(str))
          .map(s -> s+",")
          .forEach(System.out::print);
    }

运行结果:
a,b,c,d,e,f,a,g,h,

flatMap是把高纬度流变为低纬度流。

flatmap变换

str1,str2,str3作为Stream<String[]>中的元素,可以看做是二维的数组,经过flatMap变换,Stream<String[]>就变为了Stream<String>,由二维变为了一维。


3.3拆分合并流操作

  • limit

限制,返回 Stream 的前面 n 个元素

Arrays.asList(1,2,3,4,5)
      .stream()
      .limit(3)
      .forEach(System.out::print);

运行结果:123

  • skip

跳过Stream前的n个元素

Arrays.asList(1,2,3,4,5)
      .stream()
      .skip(2)
      .forEach(System.out::print);

运行结果:345

  • concat

static <T> Stream<T> concat(Stream<? extends T> a, Stream<? extends T> b)
将两个Stream合并成一个,这个方法一次只能用来合并两个Stream,不能一次多个Stream合并。

private static void concatStream() {
    Stream<Integer>stream1=Arrays.asList(1,2,3).stream();
    Stream<String>stream2=Arrays.asList("a","b","c").stream();
    Stream.concat(stream1,stream2).forEach(System.out::print);
}

运行结果:123abc


3.4流的排序

sorted()方法是个元素相关的方法,和整体的数据有关系。

  • sorted(),无参方法
Arrays.asList(3,1,4,5,2)
      .stream()
      .sorted()
      .forEach(System.out::print);

运行结果:123456
使用sorted()这个方法,要求Stream中的数据必须实现了Comparable接口

  • sorted(Comparator< ? super T > comparator)
    例:按照字符串长度进行排序
Arrays.asList("ae","f","gqet","ertyu","zxc")
        .stream()
        .sorted((s1,s2)-> Integer.compare(s1.length(), s2.length()))
        .forEach(System.out::println);

运行结果:
f ae zxc gqet ertyu


若两个字符串长度相同,按照字母顺序排列,可以用ComparatorthenComparaimg()

Arrays.asList("ae", "f", "gqet", "abcd", "ertyu", "zxc")
      .stream()
      .sorted(
               Comparator.comparing(String::length)
                         .thenComparing(String::compareTo)
             )
      .forEach(System.out::println);

运行结果:
f ae zxc abcd gqet ertyu


反转排序:Comparatorreversed()

//数字
Arrays.asList(2,3,4,1,5)
      .stream()
      .sorted(Comparator.reverseOrder())
      .forEach(System.out::print);
//字符串
Arrays.asList("ae", "f", "gqet", "abcd", "ertyu", "zxc")
      .stream()
      .sorted(Comparator.comparing(String::length).reversed())
      .forEach(System.out::println);

如果Comparator.comparing()方法中是非方法引用的Lambda表达式,就无法直接使用.reversed()


parallel().sorted()之后,不能直接使用forEach(),要使用forEachOrdered()。并行Stream和sorted()并不会冲突。

使用forEach()

Arrays.asList(1,4,5,2,3,6,8,9,7)
      .stream()
      .parallel()
      .sorted()
      .forEach(System.out::print);

运行结果:378692415

使用forEachOrdered():

Arrays.asList(1,4,5,2,3,6,8,9,7)
      .stream()
      .parallel()
      .sorted()
      .forEachOrdered(System.out::print);

运行结果:123456789


4.Stream的结果处理

  • 遍历forEach
  • 聚合reduce
  • Optional类型
  • 收集collect

4.1聚合reduce

reduce()可以实现从一组数据中生成一个数据,这个方法有三种形式:

  • Optional<T> reduce(BinaryOperator<T> accumulator)
  • T reduce(T identity, BinaryOperator<T> accumulator)
  • <U> U reduce(U identity,BiFunction<U,? super T,U> accumulator,BinaryOperator<U> combiner)

例:求累加和

Arrays.asList(1,2,3)
      .stream()
      .reduce((sum,i)-> sum = sum+i)
      .ifPresent(System.out::print);

4.2Optional

Optional是一种容器,可以存储一些值和null。利用这个类,可以进行null的判断,能够有效的避免NullPointerException

  • get(),可以拿到Optional中的值,没有值则抛出空指针异常
  • isPresent(),有非空的值,返回true,否则返回false
  • ifPresent(),public void ifPresent(Consumer<? super T> consumer)这个方法中需要一个Consumer接口。如果有非空的值,就执行指定的Consumer的方法来处理这个非空的值;如果为空,则啥都不做

reduce()操作返回的就是Optional


4.3收集collect

collect()可以将Stream流转变成集合

List<Integer>list= Arrays.asList(1,2,3,4,5)
                         .stream()
                         .filter(i-> i>3)
                         .collect(Collectors.toList());
list.forEach(System.out :: print);

5.最后

Java8 常见的函数式接口多看看。

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

推荐阅读更多精彩内容

  • Int Double Long 设置特定的stream类型, 提高性能,增加特定的函数 无存储。stream不是一...
    patrick002阅读 1,267评论 0 0
  • Streams 原文链接: Streams 原文作者: shekhargulati 译者: leege100 状态...
    忽来阅读 5,511评论 3 32
  • 前言: 讲Stream之前,先来用个小需求带入本文。毕竟代码看的最清楚。 正文: 项目某个页面有个需求,将关键词和...
    T9的第三个三角阅读 2,390评论 1 9
  • Jav8中,在核心类库中引入了新的概念,流(Stream)。流使得程序媛们得以站在更高的抽象层次上对集合进行操作。...
    仁昌居士阅读 3,619评论 0 6
  • 从不称呼你的名字 愿意借以各种秘密的代号 有时是一种动物或音调 有时是一个名词或形容词 也可以是语气词 这是一种快...
    鼠想说的阅读 574评论 20 19