1. 函数式接口
1. 通过在接口里面添加一个抽象方法,这些方法可以直接从接口中运行。 2. 如果一个接口定义了唯一一个抽象方法,那么这个接口就成为函数式接口。 3. 引入了新注解:@FunctionalInterface。 1. 放到一个接口之前,表示这个接口是函数式接口。 2. 非必须的,如果接口只包含一个方法的接口,虚拟机会自动判断。 4. e.g. java.lang.Runnable就是一个函数式接口。 @FunctionalInterface public interface Runnable { public abstract void run(); } 2. Lambda表达式 1. 重要属性:我们能够使用Lambda实例化它们,Lambda表达式让你能够将函数作为方法参数,或者将代码作为数据传递。 2. 三部分组成: 1. 一个括号内用逗号分隔的形参 2. 一个箭头符号:-> 3. 方法体 3. 语法: (parameter) ->expression body 4. 重要特征: 1. 可选的类型声明:不用声明参数类型,编译器从参数值判断是什么类型。 2. 可选的参数周围的括号:声明单个参数可以不使用括号,多个参数,括号是必须的。 3. 可选的大括号:如果表达式体中只有一个语句,不必使用大括号括起来。 4. 可选的返回关键字:方法体为表达式,该表达式的值作为返回值返回;方法体为代码块,必须用{}包裹起来,且需要一个return返回值,但若返回值是void,则无需返回值。 5. 为了更加简化lambda表达式,出现了方法引用 1. lambda表达式 1. Function<Integer, String> f = (t) -> String.valueOf(t) 2. 方法引用 1. Function<Integer, String> f2 = String::valueOf; 6. Java8在java.util.function中增加了一些新的函数式通用接口: 1. Function<T, R>:将T作为输入,返回R作为输出。 2. Predicate<T>:将T作为输入,返回一个布尔值作为输出。 3. Consumer<T>:将T作为输入,不返回任何内容,表示在单个参数上的操作。 3. 接口的增强 1. 在接口中可以添加使用default关键字修饰的非抽象方法,还可以在接口中定义静态方法。 2. 扩展方法: 1. Java8允许我们给接口添加一个非抽象的方法实现,只需要使用default关键字即可。 2. 扩展方法不能够重载Object中的方法。 3. 静态方法: 1. 在接口中,还允许定义静态的方法。 2. 接口中的静态方法可以用接口直接调用。 4. 集合之流式操作 1. 通过流式操作(Stream),可以实现对集合(Collection)的秉性处理和函数时操作。 2. 根据返回结果不同,流式操作分为中间操作和最终操作。 1. 最终操作返回一特定类型的结果。 2. 中间操作返回流本身。 3. 流式操作实现了集合的过滤、排序、映射等功能。 4. Stream和Collection集合的区别: 1. Collection是一种静态的内存数据结构,Stream是有关计算的。 2. Collection主要面向内存,存储在内存中;Stream主要面向CPU,通过CPU实现计算。 5. 串行和并行的流 1. 串行流上的操作是在一个线程中依次执行,并行流则是多个线程同时执行。 2. 并行和串行的流可以相互切换: 1. 通过stream.sequenial()返回串行的流 2. 通过stream.parallel()返回并行的流 3. 串行和并行例子: 1. (int) ((Stream) list.stream().sequential()).sorted().count(); 2. (int) ((Stream) list.stream().parallel()).sorted().count(); 6. 中间操作 1. 该操作会保持stream处于中间状态,允许做进一步的操作。它返回的还是stream,允许更多的链式操作。 2. 常用的中间操作: 1. filter():对元素进行过滤 2. sorted():对元素排序 3. map():元素的映射 4. distinct():去除重复元素 5. subStream():获取子Stream等 3. e.g. 对一个字符串集合进行过滤,返回以”s”开头的字符串集合,并将该集合依次打印出来 1. list.stream().filter((s) -> s.startsWith(“s”)).forEach(System.out::println); 7. 终止操作 1. 流的最后一个操作,一旦被调用,Stream就到了一个终止状态,而且不能再使用了。 2. 常用的终止操作: 1. forEach():对每个元素做处理。 2. toArray():把元素导出到数组。 3. findFirst():返回第一个匹配的元素。 4. anyMatch():是否有匹配的元素等。 5. 注解的更新 1. 亮点更新:类型注解和重复注解。 2. JDK8以前,注解只能在声明的地方使用,现在可以为任何东西添加注解:局部变量、类和接口,就连方法的异常都能添加注解。 3. 新增的两个注释的程序元素类型ElementType.TYPE_USE和ElementType.TYPE_PARAMETER用来描述注释的新场合。 4. ElementType.TYPE_PARAMETER表明该注解能写在类型变量的声明语句中,ElementType.TYPE_USE表明该注解能写在使用类型的任何语句中(例如声明语句、范型和强制转换语句中的类型)。 5. JDK8虽然没有自带类型检测的框架,但可以通过Checker Framework这样的第三方工具,自动检测和确认软件的缺陷。 6. 为了能在编译期间就检测出问题,可以使用类型注解结合Checker Framework提前检测出来 1. 导入Checker Framework包 1. import org.checkerframework.checker.nullness.qual.NonNull; 2. 类型注解 1. Object obj = null; 7. 重复注解 1. 在JDK8以前,相同的注解在同一个地方只能声明一次,不能声明多次。 2. JDK8引入了重复注解机制,相同的注解可以在同一个地方声明多次。 3. 重复注解机制本身必须用@Repeatable注解。 6. 安全性 1. 支持更强的基于密码的加密算法,比如基于AES加密算法,PBEWithSHA256AndAES_128 和PBEWithSHA512AndAES_256,已经被加入进来。 2. 在客户端,TLS1.1 和 TLS1.2 被设为默认启动。并且可以通过新的系统属性包 jdk.tls.client.protocols 来对它进行配置。 3. Keystore 的增强。 4. 支持安全的随机数发生器。SecureRandom 类的 getInstanceStrong 方法。 5. JSSE(Java(TM) Secure Socket Extension)服务器端开始支持 SSL/TLS 服务器名字识别 SNI(Server Name Indication)扩展。 6. 安全性比较差的加密方法被默认禁用。默认不支持 DES 相关的 Kerberos 5 加密方法。 7. IO/NIO的改进 1. 改进了java.nio.charset.Charset的实现,使编码和解码的效率得以提升。 2. 精简了 jre/lib/charsets.jar 包。 3. 优化了 String(byte[],*) 构造方法和 String.getBytes() 方法的性能。 4. 增加了一些新的 IO/NIO 方法,使用这些方法可以从文件或者输入流中获取流(java.util.stream.Stream),通过对流的操作,可以简化文本行处理、目录遍历和文件查找。 1. BufferedReader.line(): 返回文本行的流 Stream<String>。 2. File.lines(Path, Charset):返回文本行的流 Stream<String>。 3. File.list(Path): 遍历当前目录下的文件和目录。 4. File.walk(Path, int, FileVisitOption): 遍历某一个目录下的所有文件和指定深度的子目录。 5. File.find(Path, int, BiPredicate, FileVisitOption... ): 查找相应的文件。 5. e.g. 用流式操作列出当前目录下的所有文件和目录: 1. Files.list(new File(".").toPath()).forEach(System.out::println); 8. 全球化功能 1. 新的 java.time 中包含了所有关于时钟(Clock),本地日期(LocalDate)、本地时间(LocalTime)、本地日期时间(LocalDateTime)、时区(ZonedDateTime)和持续时间(Duration)的类。 2. Date 类新增了 toInstant() 方法,用于把 Date 转换成新的表示形式。