Java8 Stream系列(一)从入坑到沉迷

不想再用for嵌套for操作了,java8 带来了新的API —— Stream,非常强大!
Stream中文翻译成流,是一个支持串行和并行操作元素的序列,也是Lambda表达式配合使用的强大工具。

源码在java.util.stream中,感兴趣可以阅读阅读。

0x00 java8 中的流是什么

在编程中,对一串数据进行0个或者多个中间操作后,最后再获得结果。这个操作在没有流的情况下一般会涉及到多次循环,这是非常低效的。

流是为了处理一串数据(sequence),而不需要多次循环的一种方式。

流在操作序列的时候,会将数据放在一个叫Stream Pipeline的地方,这个地方会有三部分

  • 源(一般为集合)
  • 0或多个中间操作 (一般为惰性操作,不会直接操作数据)
  • 终止操作 (一般为求最终值,这时流的整个流程结束)

流支持并行操作,而迭代器,for循环都是串行操作,所以流在多核处理上有强大优势。


流处理模型

1x00 Stream的类型和创建方式

  • 创建流
// 从数组创建
        int [] source = {1,2,3,4,5,6};
        IntStream s = Arrays.stream(source);
// 从集合创建
        List list = Arrays.asList(1,2,3,4,5);
        Stream s2 = list.stream();
// 创建1到10的流
        IntStream s3 = IntStream.range(1,10);
//  直接创建
        Stream s4 = Stream.of("wo", "ai", "?")
  • 其他流
    此外,流还提供了几种包装好的流:
// 支持串行并行操作的序列,元素只有double类型的流
DoubleStream 
// 支持串行并行操作的序列,元素只有int类型的流
IntStream
// 支持串行并行操作的序列,元素只有long类型的流
LongStream

2x00 常用的流方法

这里不过多提及,最好看一看API文档,我这里举一些常用的例子

// (惰性操作)中间操作,遍历
Stream<T> map(Function<? super T,? extends R> mapper)

// (及早求值操作)终止操作,遍历
void forEach(Consumer<? super T> action)

例子:

// 将元素的平方打印出来
int[] nums = {2,3,4,5,6};
Arrays.stream(nums)
    .map(i->i*i)
    .forEach(System.out::println);
运行
// 将元素中的所有偶数累加求和
int[] nums = {2, 3, 4, 5, 6};
System.out.println(
        Arrays.stream(nums)
                .map(i -> i % 2 == 0 ? i : 0)
                .reduce(0, Integer::sum)
);
运行结果
// flatMap处理嵌套的list
        List<List<Integer>> ll =
                Arrays.asList(
                        Arrays.asList(1, 2, 3),
                        Arrays.asList(11, 22, 33),
                        Arrays.asList(0xF1, 0xF2, 0xF3)
                );

        ll.stream()
                .flatMap(list -> list.stream())
                .map(i -> 2 * i)
                .forEach(i -> System.out.println(i));
运行结果

假设有N条营业数据,前5条是无关的测试数据,中间10条是要参加考核的,参与考核的需要知道其中超过50w(包括50)的数据的交易额平均值,其他不参与考核的忽略。
测试数据如下:
{11, 9, 2, 13, 1, 2, 99, 54, 23, 66, 70, 23, 46, 50, 100, 10, 24, 18, 19, 2};

  Stream<Integer> trans = Stream.of(11, 9, 2, 13, 1, 2, 99, 54, 23, 66, 70, 23, 46, 50, 100, 10, 24, 18, 19, 2);

        IntSummaryStatistics all = trans
// 前5条跳过,2, 99, 54, 23, 66, 70, 23, 46, 50, 100, 10, 24, 18, 19, 2
                .skip(5)
// 取10条考核交易 2, 99, 54, 23, 66, 70, 23, 46, 50, 100
                .limit(10)
// 将50以下的交易剔除 99, 54, 66, 70, 50, 100
                .filter(i -> i >= 50)
// 转换成数字。如果是IntStream 则不需要转换
                .mapToInt(i->i)
// 将流的统计结果放入包装对象中
                .summaryStatistics();
// 交易总量 439w,平均值为439/6
        System.out.println(all.getAverage());
运行结果

以上为流的一些基础使用方法。后续会有一些详细的补充,容我后面填坑。

3x00 流的特性

  • 基于集合或者序列
  • 流不存储值,也不能重复使用,数据通过管道的方式进行操作
  • 每个操作都是函数式的,对流的操作不会影响源数据
  • 多数操作(排序,映射,过滤等),可以延迟实现

基于集合和序列就不写例子了,不存储值也是一个概念,下面验证一下流不能重复使用。

3x01 不能重复使用
        Stream<Integer> trans = Stream.of(11, 9, 2);
        trans.forEach(i -> System.out.println(i));
        trans.reduce(0, Integer::sum);

当我第二次使用trans时,报错了。


运行结果

流只能使用一次,无法重复使用

3x02 验证流延迟操作

流只要在终止操作(及早求值)时,才会对数据统一做操作,在没有遇到求值操作的时候,惰性操作代码不会被执行。

        Stream<Integer> trans = Stream.of(11, 70, 23, 46, 50, 100, 10, 24, 18, 19, 2);
        trans.map(i->{
            System.out.println(i);
            return i;
        });
运行结果,上面都没打印
3x02 不影响源数据

可以创建一个List去实践,这里不写代码,当流执行完成之后,源List的数据是不会发生变化的
大家可以自己实践一下

流使用时注意点,我会在第二篇中更新,希望不会拖很久

by:Zing ;感谢阅读,喜欢的朋友可以赞一下,或者关注我。
转载请注明出处:https://micorochio.github.io/2018/01/22/the-stream-in-java8-01/

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

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,563评论 18 139
  • Jav8中,在核心类库中引入了新的概念,流(Stream)。流使得程序媛们得以站在更高的抽象层次上对集合进行操作。...
    仁昌居士阅读 3,617评论 0 6
  • Java8 in action 没有共享的可变数据,将方法和函数即代码传递给其他方法的能力就是我们平常所说的函数式...
    铁牛很铁阅读 1,201评论 1 2
  • Streams 原文链接: Streams 原文作者: shekhargulati 译者: leege100 状态...
    忽来阅读 5,510评论 3 32
  • 正如某最热手游里的台词,“别浪,猥琐发育”“稳住,我们能赢”一样,我不成功、也不曾成功、或许也不能成功,但我以“猥...
    209fbd894260阅读 662评论 4 4