【Java进阶篇】——第11篇:Java 8 新特性及使用

打印 上一主题 下一主题

主题 911|帖子 911|积分 2733

第11篇:Java 8 新特性及使用

Java 8 是一次里程碑式的更新,引入了多项革新特性,极大地提升了开辟效率和代码表现力。本文将从 Lambda表达式Stream API时间日期APIOptional类 等核心特性出发,联合实战场景和最佳实践,全面剖析Java 8的核心功能。

1. Lambda表达式与函数式编程

1.1 Lambda表达式基础

Lambda表达式答应以简洁的语法实现函数式接口(仅含一个抽象方法的接口),替代传统的匿名内部类。
语法结构:
  1. (参数列表) -> { 代码逻辑 }
复制代码
示例:线程创建对比
  1. // 传统写法
  2. new Thread(new Runnable() {
  3.     @Override
  4.     public void run() {
  5.         System.out.println("Thread running");
  6.     }
  7. }).start();
  8. // Lambda简化
  9. new Thread(() -> System.out.println("Thread running")).start();
复制代码
1.2 函数式接口

Java 8 内置了四大核心函数式接口:


  • Consumer<T>:接收一个参数,无返回值。
    1. Consumer<String> print = s -> System.out.println(s);
    2. print.accept("Hello");
    复制代码
  • Supplier<T>:无参数,返回一个值。
    1. Supplier<Double> random = Math::random;
    2. System.out.println(random.get());
    复制代码
  • Function<T, R>:接收T范例参数,返回R范例。
    1. Function<String, Integer> length = String::length;
    2. System.out.println(length.apply("Java")); // 4
    复制代码
  • Predicate<T>:接收T范例参数,返回布尔值。
    1. Predicate<Integer> isEven = n -> n % 2 == 0;
    2. System.out.println(isEven.test(4)); // true
    复制代码
1.3 方法引用

进一步简化Lambda表达式:


  • 静态方法引用:ClassName::staticMethod
    1. List<Integer> numbers = Arrays.asList(1, 2, 3);
    2. numbers.forEach(System.out::println);
    复制代码
  • 实例方法引用:instance::method
    1. String str = "Java";
    2. Supplier<Integer> length = str::length;
    复制代码
  • 构造器引用:ClassName::new
    1. Supplier<List<String>> listSupplier = ArrayList::new;
    复制代码

2. Stream API

Stream API 提供了一种声明式处理集合数据的方式,支持次序和并行操纵,极大简化了集合处理。
2.1 Stream操纵分类



  • 中心操纵:返回新Stream,延迟执行(如filter, map, sorted)。
  • 终端操纵:触发盘算,关闭Stream(如forEach, collect, count)。
示例:集合处理
  1. List<String> languages = Arrays.asList("Java", "Python", "C++", "Go");
  2. // 过滤长度>3,转大写,排序,收集为List
  3. List<String> result = languages.stream()
  4.     .filter(s -> s.length() > 3)
  5.     .map(String::toUpperCase)
  6.     .sorted()
  7.     .collect(Collectors.toList());
  8. // 输出:[C++, GO, JAVA, PYTHON]
复制代码
2.2 并行流加速处理

通过parallelStream()利用多核CPU提升性能:
  1. List<Integer> numbers = IntStream.range(1, 10_000_000).boxed().collect(Collectors.toList());
  2. // 顺序流计算总和
  3. long sum1 = numbers.stream().mapToLong(Integer::longValue).sum();
  4. // 并行流计算总和
  5. long sum2 = numbers.parallelStream().mapToLong(Integer::longValue).sum();
复制代码
2.3 常用收集器(Collectors)



  • 转换为集合:toList(), toSet(), toMap()
  • 分组统计:groupingBy(), partitioningBy()
  • 聚合盘算:summingInt(), averagingDouble(), maxBy()
示例:统计单词频率
  1. List<String> words = Arrays.asList("apple", "banana", "apple", "orange");
  2. Map<String, Long> frequency = words.stream()
  3.     .collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
  4. // 输出:{apple=2, orange=1, banana=1}
复制代码

3. 时间日期API(java.time)

Java 8 全新的时间日期API解决了旧版Date和Calendar的设计缺陷,提供不可变、线程安全的类。
3.1 核心类



  • LocalDate:日期(年代日)。
    1. LocalDate date = LocalDate.now(); // 当前日期
    2. LocalDate independenceDay = LocalDate.of(2023, Month.JULY, 4);
    复制代码
  • LocalTime:时间(时分秒)。
    1. LocalTime time = LocalTime.parse("15:30:45");
    复制代码
  • LocalDateTime:日期时间组合。
    1. LocalDateTime dateTime = LocalDateTime.of(2023, 12, 31, 23, 59);
    复制代码
  • Duration:时间隔断(基于时间单位)。
    1. Duration duration = Duration.between(startTime, endTime);
    复制代码
  • Period:日期隔断(基于年、月、日)。
    1. Period period = Period.between(startDate, endDate);
    复制代码
3.2 格式化与剖析

  1. DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
  2. LocalDateTime dateTime = LocalDateTime.parse("2023-08-25 14:30:00", formatter);
  3. String formatted = dateTime.format(formatter); // "2023-08-25 14:30:00"
复制代码

4. Optional类

Optional用于优雅处理null值,避免空指针异常(NPE)。
4.1 根本使用

  1. Optional<String> optional = Optional.ofNullable(getName());
  2. // 存在值时执行操作
  3. optional.ifPresent(name -> System.out.println("Name: " + name));
  4. // 提供默认值
  5. String name = optional.orElse("Unknown");
  6. // 抛出异常
  7. String value = optional.orElseThrow(() -> new IllegalArgumentException("值不能为空"));
复制代码
4.2 链式操纵

  1. Optional<User> user = Optional.ofNullable(getUser());
  2. String street = user.map(User::getAddress)
  3.                    .map(Address::getStreet)
  4.                    .orElse("No street");
复制代码

5. 接口默认方法与静态方法

Java 8 答应接口包含默认方法和静态方法,增强接口的扩展能力。
5.1 默认方法

  1. public interface Vehicle {
  2.     void run();
  3.     default void honk() {
  4.         System.out.println("Beep beep!");
  5.     }
  6. }
  7. public class Car implements Vehicle {
  8.     @Override
  9.     public void run() {
  10.         System.out.println("Car is running");
  11.     }
  12. }
复制代码
5.2 静态方法

  1. public interface MathUtils {
  2.     static int add(int a, int b) {
  3.         return a + b;
  4.     }
  5. }
  6. int sum = MathUtils.add(3, 5); // 8
复制代码

6. 其他新特性

6.1 重复注解

答应在同一位置多次使用相同注解:
  1. @Retention(RetentionPolicy.RUNTIME)
  2. public @interface Roles {
  3.     Role[] value();
  4. }
  5. @Repeatable(Roles.class)
  6. public @interface Role {
  7.     String value();
  8. }
  9. @Role("admin")
  10. @Role("user")
  11. public class User { }
复制代码
6.2 范例注解

注解可应用于任何范例(如泛型、方法返回值):
  1. List<@NonNull String> list = new ArrayList<>();
复制代码
6.3 方法参数反射

通过Parameter类获取方法参数名(需编译时添加-parameters参数):
  1. public void printInfo(@NotNull String name, int age) {
  2.     // ...
  3. }
  4. Method method = User.class.getMethod("printInfo", String.class, int.class);
  5. Parameter[] parameters = method.getParameters();
  6. System.out.println(parameters[0].getName()); // 输出name
复制代码

7. 实战案例与最佳实践

案例1:使用Stream优化集合操纵

  1. // 传统写法
  2. List<String> filteredNames = new ArrayList<>();
  3. for (User user : users) {
  4.     if (user.getAge() > 18) {
  5.         filteredNames.add(user.getName());
  6.     }
  7. }
  8. // Stream优化
  9. List<String> filteredNames = users.stream()
  10.     .filter(user -> user.getAge() > 18)
  11.     .map(User::getName)
  12.     .collect(Collectors.toList());
复制代码
案例2:时间日期盘算

  1. LocalDate today = LocalDate.now();
  2. LocalDate nextWeek = today.plusDays(7);
  3. Period period = Period.between(today, nextWeek);
  4. System.out.println("间隔天数:" + period.getDays()); // 7
复制代码
最佳实践:


  • 优先使用Lambda和Stream:简化代码,提升可读性。
  • 避免太过并行化:并行流实用于大数据量且无状态操纵。
  • 时间处理使用java.time:替代Date和Calendar。
  • 善用Optional减少NPE:但避免滥用(如不要用于集合字段)。

8. 总结

Java 8 的革新特性为开辟者提供了更强盛的工具集:


  • Lambda与Stream:函数式编程简化集合操纵。
  • 时间日期API:更安全、更直观的时间处理。
  • Optional:优雅处理空值,减少NPE。
  • 接口增强:默认方法与静态方法提升机动性。
通过合理利用这些特性,可以显着提升代码质量、可维护性和性能。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

西河刘卡车医

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表