当前位置 博文首页 > yuanting_的博客:JAVA8 Stream新特性的玩法

    yuanting_的博客:JAVA8 Stream新特性的玩法

    作者:[db:作者] 时间:2021-08-25 10:10

    Stream lambda

    Stream 流
    将集合转换为 流 ,元素序列
    通过声明方式,对集合中的每个元素进行一系列并行或串行的流水线操作。

    数据源 流 中间操作 终端操作

    List 集合转换为 Stream 类型的流

    过滤 排序 类型转换
    终端操作,可以把 Stream 转换回集合类型 或者 打印 计数 求和 求平均 计算最大值最小值 等

    List newList = list.stream().map(Person::getName).sorted().limit(10).collect(Collectors.toList());

    List list = Arrays.asList(“x”,“a”,“d”,“c”);
    Stream stream = list.stream().sorted().limit(3);
    List newList1 = stream.collect(Collectors.toList());
    // java.lang.IllegalStateException: stream has already been operated upon or closed
    // List newList2 = stream.collect(Collectors.toList());

    流只能迭代一次

    stream()
    parallelStream()

    filter(T -> boolean)
    保留 boolean 为 true 的元素

    保留年龄为 20 的 person
    list = list.stream().filter(person -> person.getAge() == 20).collect(toList());

    distinct() 去除重复元素
    通过 equals 方法 判断两个元素是否相等

    sorted()
    sorted((T, T) -> int)

    如果流中的元素实现了 Comparable 接口,可以直接调用 sorted() 排序

    根据年龄大小来比较:
    list = list.stream().sorted((p1, p2) -> p1.getAge() - p2.getAge()).collect(toList());

    list = list.stream().sorted(Comparator.comparingInt(Person::getAge)).collect(toList());

    limit(long n) 返回前 n 个元素
    skip(long n) 跳 前 n 个元素

    map(T -> R)
    将流中的每一个元素 T 映射为 R(类似类型转换)

    List newlist = list.stream().map(Person::getName).collect(toList());

    flatMap(T -> Stream)
    将流中的每一个元素 T 映射为一个流,再把每一个流连接成为一个流

    List list = new ArrayList<>();
    list.add(“are you ok”);
    list.add(“i am fine”);

    list = list.stream().map(s -> s.split(" ")).flatMap(Arrays::stream).collect(toList());

    anyMatch(T -> boolean)
    boolean b = list.stream().anyMatch(person -> person.getAge() == 20);

    allMatch(T -> boolean)
    noneMatch(T -> boolean)

    Optional findAny()
    Optional findFirst()

    reduce((T, T) -> T) 和 reduce(T, (T, T) -> T)

    用于组合流中的元素,如求和,求积,求最大值等

    求和

    计算年龄总和:
    int sum = list.stream().map(Person::getAge).reduce(0, (a, b) -> a + b);
    int sum = list.stream().map(Person::getAge).reduce(0, Integer::sum);
    第一个参数为初始值

    可以不提供初始值 ,返回 Optional
    Optional sum = list.stream().map(Person::getAge).reduce(Integer::sum);

    long count()

    collect()
    collect(toList()) collect(toSet())

    forEach
    list.stream().forEach(System.out::println);

    数值流
    IntStream, DoubleStream, LongStream
    使用原始类型 int,double,long 避免 Box unbox

    流转换为数值流
    mapToInt(T -> int) : return IntStream
    mapToDouble(T -> double) : return DoubleStream
    mapToLong(T -> long) : return LongStream

    IntStream intStream = list.stream().mapToInt(Person::getAge);

    数值流转换为流
    Stream stream = intStream.boxed();

    数值流方法
    sum()
    max()
    min()
    average()

    数值范围
    range 和 rangeClosed

    闭区间 半开半闭区间

    1 到 10 求和
    IntStream intStream = IntStream.rangeClosed(1, 10);
    int sum = intStream.sum();

    Optional 类 解决空指针问题

    isPresent() 值存在时返回 true
    get() 获取当前值,值不存抛异常
    orElse(T) 值存在时返回该值,否则返回 T 值

    创建流

    Stream stream = Stream.of(“hello”, “Java8”);
    Stream.empty()

    根据数组创建流

    Arrays.stream(T[])
    Arrays.stream(int[])
    Arrays.stream(double[])
    Arrays.stream(long[])

    // 只取索引第 1 到第 2 位 , 切片 [1,3)
    int[] a = {1, 2, 3, 4};
    Arrays.stream(a, 1, 3).forEach(System.out::println);

    文件生成流
    Stream stream = Files.lines(Paths.get(“data.txt”));

    函数生成流
    首元素为 0,之后依次加 2
    Stream.iterate(0, n -> n + 2)
    Stream.generate(Math :: random)
    元素全为 1
    Stream.generate(() -> 1)

    collect 收集数据

    toList
    toSet
    toCollection
    toMap

    List newlist = list.stream.collect(toList());

    // Map Key 重复,报错
    Map<Integer, Person> map = list.stream().collect(toMap(Person::getAge, p -> p));

    汇总

    long count = list.stream().collect(counting());
    long count = list.stream().count();

    summingInt ,summingLong ,summingDouble

    int sum = list.stream().collect(summingInt(Person::getAge));

    int sum = list.stream().mapToInt(Person::getAge).sum();

    int sum = list.stream().map(Person::getAge).reduce(Interger::sum).get();

    函数式编程通常提供多种方式来完成同一种操作

    averagingInt,averagingLong,averagingDouble
    Double average = list.stream().collect(averagingInt(Person::getAge));
    OptionalDouble average = list.stream().mapToInt(Person::getAge).average();

    注意返回类型不同!!!

    summarizingInt,summarizingLong,summarizingDouble

    IntSummaryStatistics stat = list.stream().collect(summarizingInt(Person::getAge));

    取最值

    Optional optional = list.stream().collect(maxBy(comparing(Person::getAge)));
    Optional optional = list.stream().max(comparing(Person::getAge));

    joining 连接字符串

    String s = list.stream().map(Person::getName).collect(joining());

    String s = list.stream().map(Person::getName).collect(joining(","));

    groupingBy 分组

    Map<Integer, List> map = list.stream().collect(groupingBy(Person::getAge));

    按照年龄 age 分组,年龄相同的归为一组

    多级分组

    Map<Integer, Map<T, List>> map = list.stream().collect(groupingBy(Person::getAge, groupingBy(…)));

    按组聚合
    Map<Integer, Integer> map = list.stream().collect(groupingBy(Person::getAge, summingInt(Person::getAge)));

    partitioningBy 分区
    分区按照 true 和 false 来分

    根据年龄是否小于等于20来分区
    Map<Boolean, List> map = list.stream().collect(partitioningBy(p -> p.getAge() <= 20));

    list.parallelStream() 并行流

    流的可分解性

    ArrayList 和 LinkedList, 前者在分解方面占优

    性能

    Stream 的性能可能会低于传统的循环或者迭代器,甚至会低很多。

    创建流的开销 流只能迭代一次 重复创建流 box unbox

    函数式编程 主要是为了提高编码开发效率 及 增强代码可读性

    Java performance tutorial – How fast are the Java 8 streams?
    https://jaxenter.com/java-performance-tutorial-how-fast-are-the-java-8-streams-118830.html
    转载于:http://codefun007.xyz/view/article_detail.htm?id=543

    cs
    下一篇:没有了