概述

我们都知道sql语句可以让我们很方便实现一些需求例如,取TopN、排序、过滤等操作。学过scala的同学应该知道,scala中提供了很多的算子也可以很方便的进行一些数据的处理,java中可能就没那么多算子了,需要自定义去实现,但是现在java8中给我们提供了Stream Api弥补了这里劣势,提供了很多方法,不用sql也可以实现。

StreamApi

  1. Stream API 三部曲
    创建 Stream—> 中间操作(Transform) lazy—>终止操作(action)
创建Steeam的方式

import org.junit.Test;import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;/** 一、Stream API 的操作步骤:** 1. 创建 Stream** 2. 中间操作(Transform) lazy** 3. 终止操作(action)** 其实这个Stream 类似于Spark中的RDD操作首先创建一个Stream(存放数据的容器),* 然后调用各种算子进行transform操作,但这是一个lazy的过程,也就是不执行最后的* action操作,是不会有结果的.下面通过例子进行学习.*/
public class StreamApiTrain {// 1 创建Stream@Testpublic void test1(){/*** 方式1: 通过Collection 提供的Stream() ParallelStream()*/List<String> list = Arrays.asList("java","spark","hadoop","scala");//获取一个顺序流Stream<String> stream = list.stream();stream.forEach(System.out::println);//获取一个并行流Stream<String> stringStream = list.parallelStream();stringStream.forEach(System.out::println);/*** 方式2: 通过 Arrays 中的 stream() 获取一个数组流*/String [] strings = new String[5];Stream<String> stream1 = Arrays.stream(strings);/*** 方式3: 通过 Stream 类中静态方法 of()*/Stream<String> stream2 = Stream.of("java", "spark", "hadoop", "scala");/*** 方式4: 创建无限流*/Stream<Integer> iterate = Stream.iterate(0, x -> x + 2).limit(10);iterate.forEach(System.out::println);Stream<Double> generate = Stream.generate(()->Math.random()).limit(10);generate.forEach(System.out::println);}
Transform(中间操作)
    /*** Transform:* 1.filter 过滤* 2.limit 取Top n* 3.skip(n) —— 跳过元素,返回一个扔掉了前 n 个元素的流。若流中元素不足 n 个,则返回一个空流。与 limit(n) 互补* 4.distinct 去重* 5.sorted  自然排序   sorted(Comparator com)——定制排序*/@Testpublic void test2(){List<String> list = Arrays.asList("java","spark","hadoop","scala","hive","zookeeper","kafka","spark","java");list.stream().filter(x->{System.out.println("过滤操作");return x.length() > 4;}).limit(3).forEach(System.out::println);System.out.println("--------------------");list.stream().skip(2).forEach(System.out::println);System.out.println("--------------------");list.stream().distinct().forEach(System.out::println);System.out.println("--------------------");list.stream().sorted().forEach(System.out::println);System.out.println("--------------------");list.stream().sorted((x,y)->{if (x.length() == y.length()){return x.compareTo(y);}else {return Integer.compare(x.length(),y.length());}}).forEach(System.out::println);}
  • map vs flatMap
    /*** Transform:* map  vs  flatMap** map——接收 Lambda , 将元素转换成其他形式或提取信息。接收一个函数作为参数,该函数会被应用到每个元素上,并将其映射成一个新的元素。* flatMap——接收一个函数作为参数,将流中的每个值都换成另一个流,然后把所有流连接成一个流*/@Testpublic void test3(){List<String> list = Arrays.asList("java spark hadoop scala hive zookeeper kafka spark java");list.stream().map(String::toUpperCase).forEach(System.out::println);System.out.println("--------------------");Stream<String> stringStream = list.stream().flatMap(x -> Stream.of(x.split(" ")));stringStream.forEach(System.out::println);}
  • reduce
    /*** reduce: 该方法可以传递多个参数(源码中给了很多例子)** Optional<T> reduce(BinaryOperator<T> accumulator); 传递两个参数:第一个参数是上次函数执行的返回值(也称为中间结果),第二个参数是stream中的元素,这个函数把这两个值相加,得到的和会被赋值给下次执行这个函数的第一个参数** T reduce(T identity, BinaryOperator<T> accumulator); identity相当于给一个初始值,在初始值的基础上进行操作** <U> U reduce(U identity,*                  BiFunction<U, ? super T, U> accumulator,*                  BinaryOperator<U> combiner);* identity: 一个初始化的值;这个初始化的值其类型是泛型U,与Reduce方法返回的类型一致* accumulator: 其类型是BiFunction,输入是U与T两个类型的数据,而返回的是U类型;*              也就是说返回的类型与输入的第一个参数类型是一样的,而输入的第二个参数类型与Stream中元素类型是一样的。* combiner: 其类型是BinaryOperator,支持的是对U类型的对象进行操作;* 第三个参数combiner主要是使用在并行计算的场景下;如果Stream是非并行时,第三个参数实际上是不生效的。*/List<User> emps = Arrays.asList(new User(2, "李四", 59, 6666.66),new User(1, "张三", 18, 9999.99),new User(3, "王五", 28, 3333.33),new User(4, "赵六", 8, 7777.77),new User(1, "张三", 18, 9999.99),new User(4, "赵六", 8, 7777.77),new User(5, "田七", 38, 5555.55));@Testpublic void test4(){//计算user总人数Optional<Integer> count = emps.stream().map((e) -> 1).reduce((x,y)->x+y);//System.out.println(count.get());//计算薪水总和Double totalSalary = emps.stream().map(x -> x.getSalary()).reduce(0.00, (x, y) -> x + y);//System.out.println(totalSalary);//测试非并行Integer reduce = emps.stream().map(x -> x.getId()).reduce(2, ((x1, y1) -> {System.out.println("x1,y1   "+x1+":"+y1);System.out.println("x1+y1   "+x1+y1);return x1+y1;}), (x2, y2) -> {System.out.println("x2,y2   "+x2+":"+y2);System.out.println("x2+y2   "+x2+y2);return x2+y2;});System.out.println(reduce); //22(2+2+1+3+4+1+4+5)  非并行参数三不生效//测试并行Integer reduce1 = emps.parallelStream().map(x -> x.getId()).reduce(2, ((x1, y1) -> {System.out.println("x1,y1   "+x1+":"+y1);System.out.println("x1+y1   "+x1+y1);return x1+y1;}), (x2, y2) -> {System.out.println("x2,y2   "+x2+":"+y2);System.out.println("x2+y2   "+x2+y2);return x2+y2;});System.out.println(reduce1); //34 = (2+2)+(2+1)+(2+3)+(2+4)+(2+1)+(2+4)+(2+5)  并行参数三生效}@Testpublic void test5() {List<String> list = Arrays.asList("hello","hadoop","hive","hadoop","hadoop","hello");Map<String, List<String>> collect = list.stream().collect(Collectors.groupingBy((x)->x));System.out.println(collect.values());Stream<Map<String,Integer>> stream = collect.values().stream().map((x)->{Map<String, Integer> map=new HashMap<>();map.put(x.get(0), x.size());return map;});stream.forEach(System.out::println);}
action操作
    /*** action操作:* allMatch——检查是否匹配所有元素* anyMatch——检查是否至少匹配一个元素* noneMatch——检查是否没有匹配的元素* findFirst——返回第一个元素* findAny——返回当前流中的任意元素* count——返回流中元素的总个数* max——返回流中最大值* min——返回流中最小值* forEach-遍历元素*/@Testpublic void test6(){List<String> list = Arrays.asList("java","spark","hadoop","scala","hive","zookeeper","kafka","spark","java");boolean b = list.stream().allMatch(x -> x.length() > 3); //判断是否所以元素长度都大于3System.out.println(b);boolean b1 = list.stream().anyMatch(x -> x.length() > 4); //判断至少有一个元素长度大于4System.out.println(b1);Optional<String> first = list.stream().findFirst();System.out.println(first.get());Optional<String> any = list.stream().findAny();System.out.println(any.get());long count = list.stream().count();System.out.println(count);//注意:流进行了终止操作后,不能再次使用}/*** action操作:* collect--将流转换为其他形式。接收一个 Collector接口的实现,用于给Stream中元素做汇总的方法* collect方法中需要传递一个Collector,而Collectors类可以实现(源码中提供了很多例子)* Collectors类中提供了很多方法进行操作.*/@Testpublic void test7(){//取user中的名字放入list中List<String> collect = emps.stream().map(User::getName).collect(Collectors.toList());collect.forEach(System.out::println);//根据id进行分组Map<Integer, List<User>> collect1 = emps.stream().collect(Collectors.groupingBy(User::getId));collect1.forEach((key,value)-> System.out.println(key+":"+value));//根据薪水和年龄进行分区Map<Boolean, List<User>> collect2 = emps.stream().collect(Collectors.partitioningBy(x -> (x.getSalary() > 6000) && x.getAge()<30));collect2.forEach((key,value)-> System.out.println(key+":"+value));//取User中名字进行joining操作String collect3 = emps.stream().map(User::getName).collect(Collectors.joining(","));System.out.println(collect3);}}

java8新特性---StreamApi相关推荐

  1. Java8新特性(一)—————Lambda表达式

    关注微信公众号[行走在代码行的寻路人]获取Java学习视频及资料. 简述Java8中的新特性: 1.速度快:两个对象比较,采用红黑树替换了链表,使其速度变快新增的速度比较与链表较慢 2.新增Lambd ...

  2. 【小家java】java8新特性之---Optional的使用,避免空指针,代替三目运算符

    相关阅读 [小家java]java5新特性(简述十大新特性) 重要一跃 [小家java]java6新特性(简述十大新特性) 鸡肋升级 [小家java]java7新特性(简述八大新特性) 不温不火 [小 ...

  3. 【Java8新特性】关于Java8的Stream API,看这一篇就够了!!

    写在前面 Java8中有两大最为重要的改变.第一个是 Lambda 表达式:另外一个则是 Stream API(java.util.stream.*)  ,那什么是Stream API呢?Java8中 ...

  4. 【Java8新特性】浅谈方法引用和构造器引用

    写在前面 Java8中一个很牛逼的新特性就是方法引用和构造器引用,为什么说它很牛逼呢?往下看! 方法引用 当要传递给Lambda体的操作,已经有实现的方法了,可以使用方法引用!这里需要注意的是:实现抽 ...

  5. java8新特性_Java8新特性之Date API|乐字节

    大家好,我是乐字节的小乐,上篇文章讲述了<Java8新特性之Optional>,接下来,小乐将接着讲述Java8新特性之Date API 2019日历 Java8之Date API Jav ...

  6. Java8 新特性之流式数据处理(转)

    转自:https://www.cnblogs.com/shenlanzhizun/p/6027042.html 一. 流式处理简介 在我接触到java8流式处理的时候,我的第一感觉是流式处理让集合操作 ...

  7. java8新特性_乐字节-Java8新特性-接口默认方法

    总概 JAVA8 已经发布很久,而且毫无疑问,java8是自java5(2004年发布)之后的最重要的版本.其中包括语言.编译器.库.工具和JVM等诸多方面的新特性. Java8 新特性列表如下: 接 ...

  8. java8新特性: lambda表达式:直接获得某个list/array/对象里面的字段集合

    java8新特性: lambda表达式:直接获得某个list/array/对象里面的字段集合 比如,我有一张表: entity Category.java service CategoryServic ...

  9. java8新特性_乐字节-Java8新特性-函数式接口

    上一篇小乐带大家学过 Java8新特性-Lambda表达式,那什么时候可以使用Lambda?通常Lambda表达式是用在函数式接口上使用的.从Java8开始引入了函数式接口,其说明比较简单:函数式接口 ...

最新文章

  1. 团队-象棋游戏-设计文档
  2. mybatis关联查询
  3. 用ASP.NET Core 2.1 建立规范的 REST API -- HATEOAS
  4. 【转】小周立波张冯喜引爆达人秀 小童星家居照大曝光
  5. 谷歌浏览器开发调试工具中Sources面板 js调试等 完全介绍
  6. 正则表达式中原子的5种类型
  7. 红外技术如何应用在 3D 电视
  8. python将输出结果写入csv_Python怎么把输出整体写入CSV文件
  9. 专业的在线考试系统-快考题,支持自制题库/在线试卷答题
  10. 推荐3个免费开源的加密软件,知乎高赞
  11. 二层交换机和三层交换机
  12. 为什么要研究游戏AI呢?
  13. Dell EMC PowerEdge R740 服务器的驱动程序和固件更新
  14. 只鳞片爪聊红楼——《红楼梦》读后感笔记3200字
  15. 对比PAYPAL和国际信用卡支付的流程
  16. 论文引用参考文献和自动更新的方法
  17. 计算机系统基础实验:二进制拆弹实验
  18. 苹果手机登录王者荣耀服务器未响应,王者荣耀服务器未响应怎么办?登陆未响应解决方法...
  19. 《世界文化十万个为什么》读书笔记
  20. 企业选择MES系统不能盲目看重价格

热门文章

  1. 普通心理学-学习笔记
  2. u2020 华为_华为U2020-CME翻频操作指导
  3. 国庆节来了,品牌该怎么做好借势营销?
  4. Vue ES6 Jade Scss Webpack Gulp
  5. 方向键左右移动光标的时候光标自动覆盖所在字符
  6. PostgreSQL数据库头胎——后台一等公民进程StartupDataBase StartupXLOG函数初始化
  7. 这是我离马化腾最近的一次
  8. WordAnyTime 1.0.0发布
  9. npm包前的@ 是什么意思
  10. BUUCTF - misc [HDCTF2019]你能发现什么蛛丝马迹吗