java 8 特性总结回顾

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因其稳定性和强大的新特性,至今仍是许多企业和项目的首选版本。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值