java 8 特性总结回顾
好久没有回顾,有些遗忘了,这里再整理下
Java 8(于2014年3月发布)是Java发展史上一个里程碑式的版本,它引入了许多革命性的新特性和功能,极大地提升了代码的简洁性、可读性和开发效率,推动了函数式编程在Java中的应用。
Lambda表达式
这是Java 8最核心、最引人注目的特性。但也是一个缺陷,lambda的滥用导致的问题也很多。
- 概念:Lambda表达式允许你将函数作为一个方法的参数(即函数式编程),或者将代码像数据一样传递。它提供了一种更简洁的方式来定义匿名内部类,特别是对于只有一个抽象方法的接口(函数式接口)。
- 语法
(parameters) -> expression 或 (parameters) ->{ statements; }
parameters 是参数列表,expression 或 { statements; } 是Lambda 表达式的主体。如果只有一个参数,可以省略括号;如果没有参数,也需要空括号。
示例:
list.forEach(a-> System.out.println(a));
函数式接口
- 概念:指有且仅有一个抽象方法的接口。Lambda表达式就是用来实现这种接口的。
- 注解:@FunctionalInterface 注解可以用来标记一个接口是函数式接口,编译器会检查其是否符合定义。
常见内置接口:- Supplier:无参,有返回值(生产型)。
- Consumer:接收一个参数,无返回值(消费型)。
- Predicate:接收一个参数,返回一个boolean值(判断型)。
- Function<T, R>:接收一个参数,返回一个结果(函数型)。
示例:
定义一个函数式接口如下:
@FunctionalInterface
interface DoService
{
void doSomething(String message);
}
那么就可以使用Lambda表达式来表示该接口的一个实现
DoService doService = message -> System.out.println(message);
方法引用
- 概念:当Lambda表达式只是简单地调用一个已存在的方法时,可以使用方法引用来进一步简化代码,使其更清晰。
- 语法:对象::实例方法、类::静态方法、类::实例方法、类::new(构造器引用)。
- 示例:list.forEach(System.out::println); 等同于 list.forEach(x -> System.out.println(x));
Stream API
- 概念:引入了全新的java.util.stream包,提供了一种声明式、函数式的方式来处理集合(Collection)数据。它不是数据结构,而是对数据源(如集合、数组)进行计算操作的高级迭代器。
- Stream 使用一种类似用 SQL 语句从数据库查询数据的直观方式来提供一种对 Java 集合运算和表达的高阶抽象。
- Stream API可以极大提高Java程序员的生产力,让程序员写出高效率、干净、简洁的代码。
- 这种风格将要处理的元素集合看作一种流, 流在管道中传输, 并且可以在管道的节点上进行处理, 比如筛选, 排序,聚合等。
元素流在管道中经过中间操作(intermediate operation)的处理,最后由最终操作(terminal operation)得到前面处理的结果。
- 特点:
- 链式操作:可以将多个操作(如过滤、映射、排序、归约)连接起来,形成一个流水线。
- 内部迭代:由Stream API内部进行迭代,开发者只需关注“做什么”,而不是“怎么做”。
- 惰性求值:中间操作(如filter, map)是惰性的,只有在遇到终端操作(如collect, forEach)时才会执行。
- 并行处理:通过parallelStream()可以轻松地将串行流转换为并行流,利用多核CPU提升处理性能。
- 示例:从一个用户列表中筛选出年龄大于18的用户姓名,并转换为大写。
List<String> names = users.stream()
.filter(u -> u.getAge() > 18)
.map(User::getName)
.map(String::toUpperCase)
.collect(Collectors.toList());
接口的默认方法和静态方法
- 默认方法 (default):
- 允许在接口中定义一个带有具体实现的方法,使用default关键字修饰。
- 目的:为了在不破坏现有实现类的情况下,向接口添加新方法,实现向后兼容。
- 实现类可以选择重写这个默认方法,也可以直接继承使用。
- 静态方法 (static):
- 允许在接口中定义静态方法,使用static关键字修饰,并提供方法体。
- 只能通过接口名.静态方法名()的方式调用。
public interface Person{
default void print(){
System.out.println("人");
}
static void speak() {
System.out.println("说话");
}
}
新的日期和时间API
- 问题:旧的java.util.Date和Calendar类存在线程安全问题、设计不合理、API复杂等缺点。
- 解决方案:引入了全新的java.time包,设计更合理、功能更强大、线程安全。
- 核心类:
- LocalDate:表示日期(年月日)。
- LocalTime:表示时间(时分秒)。
- LocalDateTime:表示日期和时间。
- ZonedDateTime:表示带时区的日期和时间。
- Duration:表示两个时间点之间的时间量(以秒和纳秒为单位)。
- Period:表示两个日期之间的时间量(以年、月、日为单位)。
import java.time.LocalDate;
import java.time.LocalTime;
import java.time.LocalDateTime;
import java.time.Month;
public class Java8Tester {
public static void main(String args[]){
Java8Tester java8tester = new Java8Tester();
java8tester.testLocalDateTime();
}
public void testLocalDateTime(){
// 获取当前的日期时间
LocalDateTime currentTime = LocalDateTime.now();
System.out.println("当前时间: " + currentTime);
LocalDate date1 = currentTime.toLocalDate();
System.out.println("date1: " + date1);
Month month = currentTime.getMonth();
int day = currentTime.getDayOfMonth();
int seconds = currentTime.getSecond();
System.out.println("月: " + month +", 日: " + day +", 秒: " + seconds);
LocalDateTime date2 = currentTime.withDayOfMonth(10).withYear(2012);
System.out.println("date2: " + date2);
// 12 december 2014
LocalDate date3 = LocalDate.of(2014, Month.DECEMBER, 12);
System.out.println("date3: " + date3);
// 22 小时 15 分钟
LocalTime date4 = LocalTime.of(22, 15);
System.out.println("date4: " + date4);
// 解析字符串
LocalTime date5 = LocalTime.parse("20:15:30");
System.out.println("date5: " + date5);
}
}
当前时间: 2025-09-13T17:41:20.368
date1: 2025-09-13
月: SEPTEMBER, 日: 13, 秒: 20
date2: 2012-09-10T17:41:20.368
date3: 2014-12-12
date4: 22:15
date5: 20:15:30
Optional
- 概念:一个容器对象,用来封装一个可能为null的值。
- 目的:旨在提供一种优雅的方式来处理null值,避免臭名昭著的NullPointerException(空指针异常)。
- 用法:鼓励开发者显式地检查值是否存在,而不是直接调用方法。
Optional<String> optional = Optional.ofNullable(getString());
optional.ifPresent(System.out::println); // 如果存在,则打印
String result = optional.orElse("Default Value"); // 获取值,如果为空则返回默认值
其他改进
- Nashorn JavaScript引擎:提供了一个高性能的JavaScript运行时Nashorn,允许在JVM上直接运行JavaScript代码,增强了Java与JavaScript的互操作性。
- java 11已经过时,java 15不可用
- jjs:Nashorn引擎的命令行工具。
- 元空间 (Metaspace):取代了永久代(PermGen),用于存储类的元数据。元空间使用本地内存(Native Memory),默认情况下大小仅受限于物理内存,减少了OutOfMemoryError: PermGen space错误的发生。
总结
Java 8的这些特性,尤其是Lambda表达式和Stream API,彻底改变了Java的编程范式,使其代码更加简洁、优雅和富有表达力。尽管后续版本(如Java 17, 21)不断推出新功能,但Java 8因其稳定性和强大的新特性,至今仍是许多企业和项目的首选版本。
14万+

被折叠的 条评论
为什么被折叠?



