《写给大忙人看的java SE8》笔记 -- 1. lambda表达式

函数式接口

只含有一个抽象方法的接口,称为函数式接口。lambda表达式可以赋值并且仅可以赋值给函数式接口的变量。实际上编译器往往需要根据函数式接口推断lambda表达式的参数类型和返回值,比如: Comparator<String> comp = (first, second) -> Integer.compare(first.length(), second.length())。实际上,你甚至无法将一个lambda表达式赋值给一个Object类型的对象。

java.util.function包定义了各种常用的函数式接口,不过identity函数接口由Function类的静态方法提供。Runnable和Callable也是常见的函数接口。可以给函数式接口添加@FunctionalInterface标记,便于编译器检查。

lambda表达式语法

  • (String first, String second) -> { ...; return 0;}
  • (String first, String second) -> Integer.compare(first.length(), second.length()) //单条语句省略大括号
  • (first, second) ->  Integer.compare(first.length(), second.length()) //如果类型可推断
  • () -> { doWork();} //如果无参数
  • event -> System.out.println("button clicked") //只有一个参数且类型可推断,省略参数括号

函数引用

对象::实例方法

button.setOnAction(System.out::println) 等价于 button.setOnAction(event -> System.out.println(event)。对象可以是this或super,比如 this::equals 等价于 x -> this.equals(x)。

类::静态方法

Math::pow 等价于 (x,y) -> Math.pow(x,y)

类::实例方法

会在lambda表达式的第一个参数上调用该方法,比如 String::CompareTo 等价于 (x,y) -> x.compareTo(y)

构造函数引用

Button::new 等价于 x -> new Button(x)int[]::new 等价于 x -> new int[x]。可以避免泛型数组的限制,如Button[] btns = stream.toArray(Button[]::new);

作用域

lambda表达式方法体与嵌套代码块有着相同的作用域。实际上,如果方法体里引用了this,就和在嵌套块里引用this是一样的,指向的并不是lambda表达式对象。方法体里如果使用了外部的局部变量,则该变量必须是“有效的final”变量(即初始化之后不会再赋值,即便没有用final关键字修饰)。内部类原先的final约束也放宽为“有效final”。

默认方法

接口可以通过default关键字提供方法的默认实现(注意只能是接口)。

默认方法冲突的解决规则 1. 类优先。class Student extends Person implements Named {} 如果父类Person和接口Named具有同名方法,则继承父类的。2. 接口冲突。如果父类没有该方法,但是多个接口有同名方法,且至少一个接口提供了默认实现,则必须提供具体实现。

函数式接口与泛型

考虑List作为函数参数,如果函数只需要从List里面读取Person数据,那么参数可以定义为List<? extends Person>,这样传递一个List<Student>参数也没问题。如果函数只需要往List里面写入Student数据,参数可以定义为<? super Student>,这样传递一个List<Person>参数也没问题。一般来讲,读取是协变的(covariant,可以接受子类型),写入是逆变的(contravariant,可以接受父类型)。函数式接口也要遵守此惯例,比如Stream<T>的如下方法:

  • void forEach(Consumer<? super T> action)
  • Stream<T> filter(Predicate<? super T> predicate)
  • <R> Stream<R> map(Function<? super T, ? extends R> mapper)

也存在协变和逆变互相抵消的情况,这时就不需要通配符,比如 T reduce(T identity, BinaryOperator<T> accumulator)

一般来讲,你只需要在所有不是返回类型的参数类型上加上? super,并且在所有不是参数类型的返回类型上加上? extends。(simply add ? super to any argument type that is not also a return type, and ? extends to any return type that is not also an argument type.)

目录 第1lambda表达式 0 1.1 为什么要使用lambda表达式 2 1.2 lambda表达式的语法 4 1.3 函数式接口 6 1.4 方法引用 8 1.5 构造器引用 10 1.6 变量作用域 10 1.7 默认方法 14 1.8 接口中的静态方法 17 练习 18 第2章 Stream API 20 2.1 从迭代器到Stream操作 22 2.2 创建Stream 23 2.3 filter、map和flatMap方法 25 2.4 提取子流和组合流 26 2.5 有状态的转换 27 2.6 简单的聚合方法 28 2.7 Optional类型 29 2.7.1 使用Optional值 29 2.7.2 创建可选值 30 2.7.3 使用flatMap来组合可选值函数 31 2.8 聚合操作 32 2.9 收集结果 33 2.10 将结果收集到Map中 35 2.11 分组和分片 37 2.12 原始类型流 40 2.13 并行流 42 2.14 函数式接口 44 练习 45 第3章使用lambda编程 48 3.1 延迟执行 50 3.2 lambda表达式的参数 51 3.3 选择一个函数式接口 52 3.4 返回函数 55 3.5 组合 56 3.6 延迟 58 3.7 并行操作 59 3.8 处理异常 60 3.9 lambda表达式和泛型 63 3.10 一元操作 65 练习 67 第4章 JavaFX 72 4.1 Java GUI编程简史 74 4.2 你好,JavaFX! 75 4.3 事件处理 76 4.4 JavaFX属性 77 4.5 绑定 80 4.6 布局 85 4.7 FXML 91 4.8 CSS 95 4.9 动画和特殊效果 97 4.10 不寻常的控件 100 练习 103 第5章新的日期和时间API 106 5.1 时间线 108 5.2 本地日期 110 5.3 日期校正器 113 5.4 本地时间 114 5.5 带时区的时间 115 5.6 格式化和解析 119 5.7 与遗留代码互操作 122 练习 123 第6章并发增强 126 6.1 原子值 128 6.2 ConcurrentHashMap改进 131 6.2.1 更新值 132 6.2.2 批量数据操作 134 6.2.3 Set视图 136 6.3 并行数组操作 137 6.4 可完成的Future 138 6.4.1 Future 138 6.4.2 编写Future 139 6.4.3 Future流水线 139 6.4.4 编写异步操作 141 练习 143 第7章 JavaScript引擎——Nashorn 146 7.1 从命令行运行Nashorn 148 7.2 从Java运行Nashorn 149 7.3 调用方法 150 7.4 构造对象 151 7.5 字符串 153 7.6 数字 153 7.7 使用数组 154 7.8 列表和映射 155 7.9 lambda表达式 156 7.10 继承Java类及实现Java接口 157 7.11 异常 158 7.12 Shell脚本 159 7.12.1 执行Shell命令 159 7.12.2 字符串插值 160 7.12.3 脚本输入 161 7.13 Nashorn和JavaFX 162 练习 164 第8章杂项改进 166 8.1 字符串 168 8.2 数字类 168 8.3 新的数学函数 169 8.4 集合 170 8.4.1 集合类中添加的方法 170 8.4.2 比较器 171 8.4.3 Collections类 173 8.5 使用文件 173 8.5.1 读取文件行的流 173 8.5.2 遍历目录项的流 175 8.5.3 Base64编码 176 8.6 注解 177 8.6.1 可重复的注解 177 8.6.2 可用于类型的注解 179 8.6.3 方法参数反射 181 8.7 其他一些细微的改进 182 8.7.1 Null检查 182 8.7.2 延迟消息 182 8.7.3 正则表达式 183 8.7.4 语言环境 183 8.7.5 JDBC 185 练习 185 第9章你可能错过的Java 7特性 188 9.1 异常处理改进 190 9.1.1 try-with-resources语句 190 9.1.2 忽略异常 191 9.1.3 捕获多个异常 192 9.1.4 更简单地处理反射方法的异常 193 9.2 使用文件 193 9.2.1 Path 194 9.2.2 读取和写入文件 196 9.2.3 创建文件和目录 197 9.2.4
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值