zoukankan      html  css  js  c++  java
  • java 8 Stream 代码清单+API介绍

    https://www.ibm.com/developerworks/cn/java/j-lo-java8streamapi/

    构造Stream

    // 1. Individual values
    Stream stream = Stream.of("a", "b", "c");
    // 2. Arrays
    String [] strArray = new String[] {"a", "b", "c"};
    stream = Stream.of(strArray);
    stream = Arrays.stream(strArray);
    // 3. Collections
    List<String> list = Arrays.asList(strArray);
    stream = list.stream();

    数值流的构造

    //数值流有IntStream、DoubleStream、LongStream三种,目的是为了减少封箱拆箱的花费
    IntStream.of(new int[]{1, 2, 3}).forEach(System.out::println); IntStream.range(1, 3).forEach(System.out::println); IntStream.rangeClosed(1, 3).forEach(System.out::println);

    流转化为其他数据结构

    // 1. Array
    String[] strArray1 = stream.toArray(String[]::new);
    // 2. Collection
    List<String> list1 = stream.collect(Collectors.toList());
    List<String> list2 = stream.collect(Collectors.toCollection(ArrayList::new));
    Set set1 = stream.collect(Collectors.toSet());
    Stack stack1 = stream.collect(Collectors.toCollection(Stack::new));
    // 3. String
    String str = stream.collect(Collectors.joining()).toString(); //joining就是把流的每一个元素连接起来,可以传入参数表示连接的时候中间的连接符号

    流的操作分类

    • Intermediate:

             map (mapToInt, flatMap 等)、 filter、 distinct、 sorted、 peek、 limit、 skip、 parallel、 sequential、 unordered

    • Terminal:

             forEach、 forEachOrdered、 toArray、 reduce、 collect、 min、 max、 count、 anyMatch、 allMatch、 noneMatch、 findFirst、 findAny、 iterator

    • Short-circuiting:

             anyMatch、 allMatch、 noneMatch、 findFirst、 findAny、 limit

    map/flatMap(映射)

    //一对一的映射
    List<String> output = wordList.stream(). map(String::toUpperCase).collect(Collectors.toList()); List<Integer> nums = Arrays.asList(1, 2, 3, 4); List<Integer> squareNums = nums.stream().map(n -> n * n).collect(Collectors.toList());
    //一对多
    Stream<List<Integer>> inputStream = Stream.of(
    Arrays.asList(1), Arrays.asList(2, 3),Arrays.asList(4, 5, 6));
    Stream<Integer> outputStream = inputStream.flatMap(childList -> childList.stream());
    所谓flat,就是降低了这个流的维度,把每一个元素拿出来组成一个新的流,所谓的使得流扁平了

    filter

    List<String> output = reader.lines(). flatMap(line -> Stream.of(line.split(REGEXP))).
     filter(word -> word.length() > 0). collect(Collectors.toList());
    //这里我reader是BufferedReader,lines方法返回每一行的数据作为一个元素,注意Stream一次性的特点,消耗之后就不能在使用看来,在处理文件相关内容的时候要格外的注意

    forEach

    stream.filter(p -> p.getGender() == Person.Sex.MALE)
    .forEach(p
    -> System.out.println(p.getName()));
    forEach 方法接收一个 Lambda 表达式,然后在 Stream 的每一个元素上执行该表达式。
    forEach 是 terminal 操作,因此它执行后,Stream 的元素就被“消费”掉了,你无法对一个 Stream 进行两次 terminal 运算
    peek 
    对每个元素执行操作并返回一个新的 Stream
    Stream.of("one", "two", "three", "four")
     .filter(e -> e.length() > 3)
     .peek(e -> System.out.println("Filtered value: " + e))
     .map(String::toUpperCase)
     .peek(e -> System.out.println("Mapped value: " + e))
     .collect(Collectors.toList());

    findFirst

    一个 termimal 兼 short-circuiting 操作,它总是返回 Stream 的第一个元素,或者空。
    返回值类型:Optional

    reduce

    提供一个起始值(种子),然后依照运算规则(BinaryOperator),和前面 Stream 的第一个、第二个、第 n 个元素组合。从这个意义上说,字符串拼接、数值的 sum、min、max、average 都是特殊的 reduce
    Stream.reduce(0, (a, b) -> a+b)等价于sum()
    
    // 字符串连接,concat = "ABCD"
    String concat = Stream.of("A", "B", "C", "D").reduce("", String::concat); 
    // 求最小值,minValue = -3.0
    double minValue = Stream.of(-1.5, 1.0, -3.0, -2.0).reduce(Double.MAX_VALUE, Double::min); 
    // 求和,sumValue = 10, 有起始值
    int sumValue = Stream.of(1, 2, 3, 4).reduce(0, Integer::sum);
    // 求和,sumValue = 10, 无起始值,这里返回的是Optional类型
    sumValue = Stream.of(1, 2, 3, 4).reduce(Integer::sum).get();
    // 过滤,字符串连接,concat = "ace"
    concat = Stream.of("a", "B", "c", "D", "e", "F").
     filter(x -> x.compareTo("Z") > 0).
     reduce("", String::concat);

    limit/skip

    limit 返回 Stream 的前面 n 个元素;skip 则是扔掉前 n 个元素。
    limit 和 skip 对 sorted 后的运行次数无影响,就是说你不知道sorted的结果你limit没有用,不知道从哪里limit还是一样得排序

    sorted

    List<Person> personList2 = persons.stream().limit(2).sorted((p1, p2) -> p1.getName().compareTo(p2.getName())).collect(Collectors.toList());
    没有实现Comparable的要指定Comparable(Lumbda表达式)

     min/max/distinct

    BufferedReader br = new BufferedReader(new FileReader("c:\SUService.log"));
    int longest = br.lines().mapToInt(String::length).max().getAsInt();
    br.close();
    System.out.println(longest);
    
    List<String> words = br.lines().flatMap(line -> Stream.of(line.split(" "))). filter(word -> word.length() > 0).
     map(String::toLowerCase).distinct(). sorted(). collect(Collectors.toList());
    

    Match

    • allMatch:Stream 中全部元素符合传入的 predicate,返回 true
    • anyMatch:Stream 中只要有一个元素符合传入的 predicate,返回 true
    • noneMatch:Stream 中没有一个元素符合传入的 predicate,返回 true
    boolean isAllAdult = persons.stream().allMatch(p -> p.getAge() > 18);

    Stream.generate

    根据传入的Supplier 生成流,流的长度是无限的

    Stream.iterate
    iterate 跟 reduce 操作很像,接受一个种子值,和一个 UnaryOperator(例如 f)。然后种子值成为 Stream 的第一个元素,f(seed) 为第二个,f(f(seed)) 第三个,以此类推。

    Stream.iterate(0, n -> n + 3).limit(10). forEach(x -> System.out.print(x + " "));.

    用 Collectors 来进行 reduction 操作

    java.util.stream.Collectors 类的主要作用就是辅助进行各类有用的 reduction 操作,例如转变输出为 Collection,把 Stream 元素进行归组。

    Collectors .groupingBy/partitioningBy
    按照条件分类,返回一个Map

    把学生按照年龄进行分组,注意返回值的Map:key是分组的条件,val是符合条件的数据的集合
    Map<Integer, List<Person>> personGroups = Stream.generate(new PersonSupplier()). limit(100). collect(Collectors.groupingBy(Person::getAge)); Iterator it = personGroups.entrySet().iterator(); while (it.hasNext()) { Map.Entry<Integer, List<Person>> persons = (Map.Entry) it.next(); System.out.println("Age " + persons.getKey() + " = " + persons.getValue().size()); }

     

    partitioningBy 注意返回值的key是Boolean类型,就是把集合分成了两部分
    Map<Boolean, List<Person>> children = Stream.generate(new PersonSupplier()).
     limit(100).
     collect(Collectors.partitioningBy(p -> p.getAge() < 18));
    System.out.println("Children number: " + children.get(true).size());
    System.out.println("Adult number: " + children.get(false).size());

     

    总之,Stream 的特性可以归纳为:

    • 不是数据结构
    • 它没有内部存储,它只是用操作管道从 source(数据结构、数组、generator function、IO channel)抓取数据。
    • 它也绝不修改自己所封装的底层数据结构的数据。例如 Stream 的 filter 操作会产生一个不包含被过滤元素的新 Stream,而不是从 source 删除那些元素。
    • 所有 Stream 的操作必须以 lambda 表达式为参数
    • 不支持索引访问
    • 你可以请求第一个元素,但无法请求第二个,第三个,或最后一个。不过请参阅下一项。
    • 很容易生成数组或者 List
    • 惰性化
    • 很多 Stream 操作是向后延迟的,一直到它弄清楚了最后需要多少数据才会开始。
    • Intermediate 操作永远是惰性化的。
    • 并行能力
    • 当一个 Stream 是并行化的,就不需要再写多线程代码,所有对它的操作会自动并行进行的。
    • 可以是无限的
      • 集合有固定大小,Stream 则不必。limit(n) 和 findFirst() 这类的 short-circuiting 操作可以对无限的 Stream 进行运算并很快完成。

     



  • 相关阅读:
    (一)python 简单网页爬虫
    环形队列的应用
    AutoResetEvent 和 ManualResetEvent 多线程应用
    委托 和 事件
    Action 和 Func 的用法以及区别
    IIS 配置缓存
    IIS 发布双证书
    函数中返回局部变量的问题
    python函数2-函数参数
    Python基础语法6-冒泡排序
  • 原文地址:https://www.cnblogs.com/Coder-Pig/p/6789932.html
Copyright © 2011-2022 走看看