zoukankan      html  css  js  c++  java
  • 《java8实战阅读笔记》

    作为一个对java8不是特别理解的人,花了两个星期全面的读了下《java8实战》做了个流水的笔记。

    现在线上的java都是基于java8的,以后尽量使用java8的特性编程。

    一下的内容都是基于markdown的。。。 

    # java8 实战

    ## 2 通过行为参数传递代码


    行为的参数化

    1 值参数化
    2 类,匿名类,lambda


    ## 3 lambda表达式

    lambda表达式

    Comparator<Apple> byWeight =(Apple a1, Apple a2) -> a1.getWeight().compareTo(a2.getWeight());

    函数式接口

    仅仅定义了一个抽象方法

    函数描述符

    函数式接口的抽象方法的签名基本上就是Lambda表达式的签名。我们将这种抽象方法叫作 函数描述符。

    (Apple, Apple) -> int

    只有在需要函数式接口的时候才可以传递Lambda

    环绕式执行

    try{}{
    }

    java的函数式接口之predicate

    test(T t)

    函数式接口Consumer

    accept(T t)

    函数式接口Function

    R apply(T t)

    抽象方法Supplier

    T get()

    装箱和非装箱

    IntPredicate
    IntConsume
    int

    函数类型检查:符合函数特征即可用

    函数变量不推荐使用局部变量,使用时加上final


    闭包

    闭包就是一个函数的实例,且它可以无限 制地访问那个函数的非本地变量


    方法引用

    闭包就是一个函数的实例,且它可以无限 制地访问那个函数的非本地变量

    三类方法引用

    1 静态方法
    A::XX
    2 指向任意类型实例方法的方法引用
    B:xx
    3 现有对象的实例方法的方法引用
    c:xx

    构造函数引用

    A::new

    List<Integer> weights = Arrays.asList(7, 3, 4, 10);
    List<Apple> apples = map(weights, Apple::new);


    数组构造函数和父类调用

    自动生成比较器

    Comparator.comparing((Apple a) -> a.getWeight());

    inventory.sort(comparing(Apple::getWeight).reversed());

    inventory.sort(comparing(Apple::getWeight)
    .reversed()
    .thenComparing(Apple::getCountry));

    Predicate谓词复合

    Predicate<Apple> redAndHeavyAppleOrGreen =
    readApple.and(a->a.getWeight() > b.getWeight())
    .or(a -> "green".equals(a.getColor()));

    function函数复合

    andThen,先执行,再执行另外一个函数
    先把给定的函数用作compose的参数里面给的那个函 数,然后再把函数本身用于结果。


    ## 4 流

    流的定义

    1 java的api
    2 声明处理数据集合
    3 高级的数据迭代器

    流的基本定义

    1 元素序列 filter sorted map
    2 源。数据源:
    3 数据处理操作
    filter map reduce find match sort
    limit
    4 流水线
    5 内部迭代

    流与集合

    1 流只能遍历一次
    2 集合的外部迭代,流的内部迭代

    流的操作

    1 中间操作

    filter map limit sorted distinct

    2 终止操作

    collect
    foreach
    count

    ## 5 使用流


    谓词筛选

    filter
    distinct
    limit
    skip

    映射

    map
    flatmap

    查找和匹配

    allMatch anyMatch noneMatch
    findFirst findAny

    optional操作

    isPresent
    ifPresent
    T get()
    T orElse(T other)

    规约

    reduce(init, func)
    reduce(min/max)
    count

    所有的操作

    filter
    distinct
    skip
    limit
    map
    flatMap
    sorted
    anyMatch
    noneMatch
    allMatch
    findAny
    findFirst
    forEach
    collect
    reduce
    count


    数值流

    mapToInt
    boxed
    IntStream.rangeClosed

    构建流

    stream.of();
    stream.empty();
    Arrays.stream(numes);
    File.lines(
    xxx).distinct().count

    函数创建流

    stream.iterate
    Stream.generate


    ## 6 使用流收集数据


    ### 6.1 收集器 & 规约 汇总

    总数

    Collectors.counting()

    最大的 Collectors.maxBy(Comparator.comparingInt(Transaction::getValue))

    Collectors.sumInt()
    averagingInt
    joining
    reducie
    redcing()
    menu.stream().mapToInt(Dish::getCalories).sum();


    ### 6.2分组

    groupingBy 分组,多级分组

    按子组收集数据

    将收集到的结果转换为另外一种类型collectAndThen

    ### 6.3 分区

    boolean分词作为分区:partitioningBy

    collection的静态方法

    toList
    toSet
    toCollection
    counting
    summingint
    averagingInt
    joning
    maxBy
    minBy
    reducing
    collectionAndThen
    groupingBy
    partitioningBy

    收集器接口

    自己实现java的stream

    ```
    public interface Collector<T, A, R> {
    Supplier<A> supplier();
    BiConsumer<A, T> accumulator();
    Function<A, R> finisher();
    BinaryOperator<A> combiner();
    Set<Characteristics> characteristics();
    }
    ```

    ## 7 并行数据处理与性能

    并行流

    parallel

    并行流性能影响

    1 减少数字的装箱和开箱
    2 共享可变状态会影响并行流以及并行计算。
    3 如果有疑问需要测量
    4 有些操作并行比线性差
    5 流水线总成本
    6 较小数据量时不适应
    7 背后的数据结构是否易于分解
    8 中间合并步骤的代价

    流的源,可分解性

    ArrayList 极佳
    LinkedList 差
    IntStream.range 极佳
    Stream.iterate 差
    HashSet 好
    TreeSet 好


    分支/合并框架

    它实现ExecutorService接口,把任务分配给ForkJoinPool

    任务实现返回结果:RecursiveTask<R>
    不返回结果 RecursiveAction

    forkjoin的业务逻辑

    ```
    if (任务足够小或不可分) {
    顺序计算该任务
    } else {
    将任务分成两个子任务
    递归调用本方法,拆分每个子任务,等待所有子任务完成
    合并每个子任务的结果
    }
    ```

    使用分支/合并框架的最佳做法

    1 对一个任务调用join方法会阻塞调用方,直到该任务做出结果。两任务均开始后再调用
    2 不应该在RecursiveTask内部使用ForkJoinPool的invoke方法。你应该始终直接调用compute或fork方法,只有顺序代码才应该用invoke来启动并行计算。
    3 对子任务调用fork方法可以把它排进ForkJoinPool。
    4 调试使用分支/合并框架的并行计算可能有点棘手。
    5 和并行流一样,你不应理所当然地认为在多核处理器上使用分支/合并框架就比顺序计算快。

    原理工作窃取


    spliterator 可分迭代器

    ```
    public interface Spliterator<T> {
    boolean tryAdvance(Consumer<? super T> action);
    Spliterator<T> trySplit();
    long estimateSize();
    int characteristics();
    }
    ```

    ## 8 重构,测试和调试


    改善可读写和灵活性

    1 使用匿名类代替lambda
    2 stream的方法引用
    3 切换到stream

    增加代码的灵活性

    1 使用函数式接口
    2 延迟执行
    3 环绕执行

    使用lambda重构设计模式

    1 策略模式,函数式接口
    2


    lambda表达式使用

    peek日志调试流


    ## 9 默认方法

    接口可以使用默认反复


    默认接口方法冲突的问题

    1 类最优
    2 子接口最优
    3 显示覆盖



    ## 10 Optional取代null

    创建


    提取

    map 获取Optional里面的数据
    flatMap 从其他部分获取Optional
    get
    orElse
    orElseGet
    orElseThroww
    ifPresent
    filer过滤

    详细操作

    empty
    filter
    flatMAP
    get
    ifPresent
    isPresent
    map
    of ofNullable orElse orElseGet orElseThrow

    OptionalUtility工具


    ## 11 CompletableFuture

    future工具

    ```
    ExecutorService executor = Executors.newCachedThreadPool(); Future<Double> future = executor.submit(new Callable<Double>() {
    public Double call() {
    })

    try {
    Double result = future.get(1, TimeUnit.SECONDS);
    } catch (ExecutionException ee) { // 计算抛出一个异常
    } catch (InterruptedException ie) { // 当前线程在等待过程中被中断
    } catch (TimeoutException te) { // 在Future对象完成之前超过已过期
    }

    ```
    future的局限性

    1 Future很难直接表述多个Future 结果之间的依赖性,开发中,我们经常需要达成以下目的:
    2 将两个异步计算合并为一个(这两个异步计算之间相互独立,同时第二个又依赖于第一个的结果)
    3 等待 Future 集合中的所有任务都完成。
    4 仅等待 Future 集合中最快结束的任务完成,并返回它的结果。


    CompletableFuture

    只有当每个操作很复杂需要花费相对很长的时间

    基本用法

    ```
    Async结尾的方法都是可以异步执行的,如果指定了线程池,会在指定的线程池中执行,如果没有指定,默认会在ForkJoinPool.commonPool()中执行。下面很多方法都是类似的,不再做特别说明。

    四个静态方法用来为一段异步执行的代码创建CompletableFuture对象,方法的参数类型都是函数式接口,所以可以使用lambda表达式实现异步任务

    runAsync方法:它以Runnabel函数式接口类型为参数,所以CompletableFuture的计算结果为空。

    supplyAsync方法以Supplier<U>函数式接口类型为参数,CompletableFuture的计算结果类型为U。
    ```


    ```
    public static CompletableFuture<Void> runAsync(Runnable runnable)
    public static CompletableFuture<Void> runAsync(Runnable runnable, Executor executor)
    public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier)
    public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier, Executor executor)

    public <U> CompletionStage<U> thenApply(Function<? super T,? extends U> fn);
    public <U> CompletionStage<U> thenApplyAsync(Function<? super T,? extends U> fn);
    public <U> CompletionStage<U> thenApplyAsync(Function<? super T,? extends U> fn,Executor executor);

    ```

    ## 12 新的日期和时间API

    新的日期库出现的原因


    新日期类

    LocationDate LocationTime instant Duration period

    时间范围 Period Duration


    操作和解析

    不同时区和历法


    ## 13 函数式的思考

    实现和维护系统

    1 类的结构合理
    2 提供指标
    3 耦合性,内聚性

    难题

    1 共享的可变数据

    命令式编程


    声明式编程

    称述问题

    函数式编程:用函数进行编程的方式

    1 修改本地变量
    2 只引用不可修改的对象
    3 函数或者方法不能抛出异常 使用Option<T>

    引用的透明性:同一值,输出不变

    面向对象和函数式的对比

    1 万物是对象
    2 引用透明,不应该有修改对象

    考虑编程问题时,采用函数式的方法,关注函数的输入参数以及输出结果


    递归和迭代

    函数编程不会包含while和for的迭代器

    ## 14 函数式编程的技巧


    ### 无处不在的函数

    高阶函数:至少一个函数为参数,返回一个函数,注意函数式的副作用

    科里化:返回函数


    ### 持久化数据结构

    函数式方法不能修改传入参数或者全局参数

    ### stream的延迟计算?

    stream只允许使用一次

    stream不允许递归定义

    延迟列表


    ### 模式匹配


    ### 杂项

    缓存或记忆表

    stream的特定

    1.stream不存储数据
    2.stream不改变源数据
    3.stream的延迟执行特性


    ## 15 面向对象和函数式编程的混合

    jvm平台函数式语言 scala

    scala 更好的流式编程,更好的函数式编程


    ## 16 结论以及java的未来

    尽量使用新特性







  • 相关阅读:
    剑指Offer(书):重建二叉树
    剑指Offer(书):从尾到头打印链表
    剑指Offer(书):替换空格
    剑指Offer(书):二维数组中的查找
    剑指Offer(书):数组中重复的数字
    剑指Offer(书):实现单例模式
    Centos 7安装Mysql5.7
    3000客接口迁移一记
    安装完Centos 7后的一些处理
    算法笔记—入门篇(2)—算法初步(更新中......)
  • 原文地址:https://www.cnblogs.com/beckbi/p/11334051.html
Copyright © 2011-2022 走看看