博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
《Java8实战》读书笔记
阅读量:6083 次
发布时间:2019-06-20

本文共 6105 字,大约阅读时间需要 20 分钟。

hot3.png

#1. 引入更多编程概念、编程工具,简洁、灵活地编写代码。

优化步骤:

1)进一步复用代码,抽取公共的逻辑代码,参数化可变的逻辑代码
2)声明式编程
3)并发编程,隐藏底层实现
##1.1 lambda表达式 进一步复用逻辑代码,行为参数化,引入思想。

###lambda表达式 相较于之前的匿名类实现行为参数化,更简洁 。有参数列表、箭头、函数主体、返回类型、异常列表。

(parameters)->expression(parameters)->{statements;}

###函数式接口

1)函数式接口:只定义一个抽象方法的接口,通常会使用@FunctionalInterface注解一下;
2)lambda表达式可以当作函数式接口的实现实例;
3)常用的函数式接口:在java.util.function包预定义了一些常用函数式接口:

Predicate
{ boolean test(T t); }Consumer
{ void accept(T t); }Function
{ R apply(T t); }Supplier
{ T get(); }UnaryOperate
extends Function
{}BinaryOperator
extends BiFunction
{}BiPredicate
{ boolean test(T t, U u); }BiConsumer
{ void accept(T t, U u); }BiFunction
{ R apply(T t, U u); }

4)原型类型特化的函数式接口:避免装箱、拆箱操作,输入参数或返回类型是原始类型;

###类型坚持、类型推断以及限制

1)lambda类型检查:lambda的类型是从使用lambda的上下文推断出来的,目标类型的抽象方法签名(函数描述符)可以兼容lambda表达式的签名。另外如果一个lambda的主体是一个语句表达式,它就和一个返回void的函数描述符兼容。
2)lambda类型推断以:既然可以推断出lambda的签名,就可以知道lambda表达式的参数类型,省去lambda中参数类型的书写。
3)限制:使用自由变量,即外层作用域中定义的变量,必须声明称final

###方法引用 方法引用:可以被看作仅仅调用特定方法的lambda的一种快捷写法,可以重复使用现有的方法来创建lambda表达式。有:

1)指向静态方法的方法引用;
2)指向任意类型实例方法的方法引用;
3)指向现有对象的实例方法的方法引用;
4)构造函数引用

###复合lambda高阶函数

##1.2 流Stream 很多业务逻辑都涉及类似数据库的集合操作,都会使用到Collection。Collection主要是为了存储和访问数据,Stream主要用于描述对数据集合Collection的计算处理(声明式处理数据集合,可以透明地并行处理)。

流:从支持数据处理操作的源生成的元素序列。 特点:1)按需计算,可以是无界的,延迟;2)只能遍历一次;3)内部迭代。

使用流:1)一个数据源来执行一个查询;2)一个中间操作链,形成一个流的流水线;3)一个终端操作,只想流水线,并能生成结果。

默认方法: java8在加入Stream时,在原来的集合系统上使用了“默认方法”得以扩展Stream功能而不用每个实现类都实现相关接口方法。

###构建流 原始类型特化流:IntStream, DoubleStream, LongStream避免装箱成本。1)每个接口都带来性的常用的数值归约方法。 2)Stream提供mapToXXX转成特化流,特化流通过boxed转回对象流。3)提供range和rangeClosed生成流。

构建方法:1)由值创建:Stream.of();2)由数组构建:Arrays.Stream();3)由文件生成:Files.line();4)由函数生成:Stream.iterate, Stream.generate

###使用流 Stream接口的方法

1)筛选和切片:filter, distinct, limit, skip ;
2)映射:map, flatMap(把一个流中的每个值都转成另一个流,然后把所有的流连接起来成为一个流);
3)查找和匹配:allMatch, anyMatch, noneMatch, findFirst, findAny;
4)归约折叠:reduce,可以支持并行计算,collect;

###用流收集数据 1)collect是一个终端操作,参数是将流中元素累计到汇总结果的各种方式(收集器)

1)预定义收集器:Collector类提供的工厂方法创建的收集器:3大功能:将流元素归约和汇总为一个值;元素分组groupingBy;元素分区partitioningBy。收集器可以复合起来进行多级分组、分区和归约。
2)自定义收集器:

public interface Collector
{ Supplier
supplier(); BiConsumer
accumulator(); BinaryOperator
combiner(); Function
finisher(); Set
characteristics(); public static
Collector
of(Supplier
supplier, BiConsumer
accumulator, BinaryOperator
combiner, Characteristics... characteristics) {... } public static
Collector
of(Supplier
supplier, BiConsumer
accumulator, BinaryOperator
combiner, Function
finisher, Characteristics... characteristics) {...} }

###并行流 底层使用分支/合并框架处理并行流,用递归方式将可以并行的任务拆分成更小的任务,在不同的线程上执行,然后将各个子任务的结果合并起来生成整体结果。

高效使用并行流

1)使用适当的基准来检查并行流性能;
2)留意装箱。自动装箱和拆箱会大大减低性能;
3)有些操作本身在并行流上的性能就比顺序流差;
4)流的操作流水线的总计算成本;
5)对于较小的数据量,选择并行流几乎从来都不是一个好的决定;
6)要考虑背后的数据结构是否易于分解;
7)流自身的特定,以及流水线中的中间操作修改流的方式,都可能会改变分解过程的性能;
8)考虑终端操作中合并步骤的代价是大是小;

Spliterator Java8的新接口,定义并行流如何拆分它要遍历的数据。

public interface Spliterator
{ boolean tryAdvance(Consumer
action); Spliterator
trySplit(); long estimateSize(); int characteristics();}

##1.3 其他 现代程序设计方法,改善代码质量 ###重构、测试、调试 改善代码的可读性:

1)用Lambda表达式取代匿名类:在匿名类中this代表类自身,Lambda里this代表包含类;匿名类可以屏蔽包含类的同名变量,而Lambda表达式不能;
2)用方法引用重构Lambda表达式;
3)用Stream API重构命令式的数据处理;

增加代码的灵活度: 1)采用函数接口;

2)有条件的延迟执行;
3)环绕执行;

Lambda表达式会使栈跟踪的分析变得更为复杂。流提供peek方法在分析Stream流水线时,可以将中间变量的值输出到日志中,常用于调试代码。

###default默认方法 Java8的接口可以通过默认方法和静态方法提供方法的代码实现。通过默认方法可以指定接口方法的默认实现,实现类如果不显示提供该方法的具体实现,就会自动继承默认的实现。这种机制可以平滑地进行接口的优化和演进。默认方法的开头以关键字default修饰,方法体与常规的类方法相同。

静态方法及接口同时定义接口以及工具辅助类是Java语言常用的一种模式,工具类定义了接口实例协作的很多静态方法。在有了默认方法后,这些辅助类就没有存在的必要了,可以把这些辅助类的静态方法转移到接口内部。

java8中抽象类和抽象接口:1)一个类只能继承一个抽象类,但是一个类可以实现多个接口;2)一个抽象类可要通过实例变量保存一个通用状态,而接口是不能有实例变量的。

默认方法的使用模式:1)可选方法;2)行为多继承:类型的多继承,利用正交方法的精简接口,组合接口

解决冲突的规则 1)类中的方法优先级最高。类或父类中声明的方法的优先级高于任何声明默认方法的优先级;

2)如果无法依据第一条进行判断,那么子接口的优先级更高:函数签名相同时,优先级选择拥有最具体实现的默认方法的接口,即如果B继承了A,那么B就比A更具体;
3)如果还是无法判断,继承了多个接口的泪必须通过显示覆盖和调用期望的方法,显示地选择使用哪一个默认方法的实现(x.super.m(...))。
C++中的菱形问题更复杂:因为是类多继承,除了方法的冲突还要考虑到变量的冲突。

###Optional 1)java8中引入了一个新的类java.util.Optional<T>对存在或缺失的变量值进行建模;

2)可以使用静态工厂方法Optional.empty,Optional.of以及Optional.ofNullable创建Optional对象。
3)Optional类支持多种方法:比如map, flatMap, filter,在概念上和Stream类相似;
4)null判断,不用isPresent:

public static final Optional
max(Optional
i, Optional
j) { return i.flatMap(a -> j.map(b -> Math.max(a, b)));}public static int readDurationWithOptional(Properties props, String name) { return ofNullable(props.getProperty(name)) .flatMap(ReadPositiveIntParam::s2i) .filter(i -> i > 0).orElse(0);}

5)orElseGet(Supplier<? extends T> other)是orElse方法的延迟调用版,Supplier方法只有在Optional对象不含只时才调用。如果创建默认值是件耗时费力的工作,可以考虑采用这种方式;

6)Optinal无法序列化

###组合式异步编程CompletableFuture 执行比较耗时的操作时,尤其是那些依赖一个或多个远程服务的操作,使用异步任务可以改善程序的性能,加快程序的响应速度。

对集合进行并行计算有2种方式:1)将其转化为并行流,利用map操作开展工作;2)枚举出集合众每一个元素,创建新的线程,在CompletableFurture内对其进行操作。后者提供了更多地灵活性,可以调整线程池的大小,进而确保整体的计算不会因为现场都在等待I/O而发生阻塞。

1)如果进行的实计算密集型的操作,并且没有I/O,那么就推荐使用Stream接口,因为实现简单,同时效率也可能是最高的(如果所有的线程都是计算密集型的,那就没有必要创建比处理器核数更多的线程);

2)如果并行的工作单元还涉及等待I/O的操作,那么使用CompletaleFuture灵活性更好,可以根据Nthreads=Ncpu*Ucpu*(1+W/C)(Ncpu是处理器的核数,Ucpu是期望的CPU利用率,W/C是等待时间与计算时间的比率)设定需要使用的线程数。这种情况不使用并行流的另一个原因:处理刘的流水线中如果发生I/O等待,流的延迟特性会让我们很难判断到底是什么时候触发了等待。

###新Date和TIme接口

TemporalField, ChronoField
Temporal:定义如何读取和操纵为时间建模的对象的值;

LocalDate:不可变对象,提供简单的日期,不含时间和时区信息

LocalTime:
LocalDateTIme:
Instant:便于机器使用,从1970-01-01开始经历的秒数

间隔:

Duration:2个Temporal对象之间的duration
Period:以年、月、日的方式对多个时间单位建模 TemporalAdjuster:

格式化:

DateFormatter:

时区:

ZoneId:区时信息 ZoneDateTime:
ZoneOffset:
OffsetDateTime:

日历系统:

Chronology:
ChronoLocalDate:
ThaiBuddhistDate:
MiguoDate:
JapaneseDate:
HijrahDate:

转载于:https://my.oschina.net/braveCS/blog/807398

你可能感兴趣的文章
Xcode 4.3 使用xcodebuild命令编译项目环境设置
查看>>
上传jar包到nexus私服
查看>>
Why Namespace? - 每天5分钟玩转 OpenStack(102)
查看>>
Project:如何分析项目中的资源分配情况
查看>>
HDU 4803 Poor Warehouse Keeper (贪心+避开精度)
查看>>
python全栈_011_Python3基本数据类型--字典
查看>>
json
查看>>
linux tomcat 用/etc/init.d/tomcat start启动报错
查看>>
高性能javascript学习笔记系列(2)-数据存取
查看>>
Spark之scala
查看>>
JSON使用
查看>>
Java 一些缩写的解释
查看>>
监控HTTP(1)
查看>>
python 操作PostgreSQL
查看>>
POJ1465:Multiple(BFS)
查看>>
使用框架页面的跳转 转
查看>>
php lock_sh共享锁 与 lock_ex排他锁
查看>>
codeigniter 对数据库的常用操作
查看>>
重装win7系统多个方法介绍
查看>>
Python之路
查看>>