Java 8引入了许多强大且实用的新特性,使得Java编程更加简洁和高效。本章将介绍其中一些最重要的特性。

8.1 Lambda表达式与函数式编程

Lambda表达式是Java 8引入的一种新语法,用于实现函数式编程。它允许你以更简洁的方式来表示匿名函数。

8.1.1 Lambda表达式的语法

Lambda表达式的基本语法如下:

  1. (parameters) -> expression
  2. // 或者
  3. (parameters) -> { statements; }

示例

  1. // 使用Lambda表达式实现Runnable接口
  2. Runnable runnable = () -> {
  3. for (int i = 0; i < 5; i++) {
  4. System.out.println("Hello from Lambda Runnable!");
  5. }
  6. };
  7. // 启动线程
  8. new Thread(runnable).start();

使用Lambda表达式替代匿名类

  1. // 使用匿名类
  2. Comparator<String> comparator1 = new Comparator<String>() {
  3. @Override
  4. public int compare(String s1, String s2) {
  5. return s1.compareTo(s2);
  6. }
  7. };
  8. // 使用Lambda表达式
  9. Comparator<String> comparator2 = (s1, s2) -> s1.compareTo(s2);
  10. // 使用Lambda表达式的Comparator进行排序
  11. List<String> list = Arrays.asList("apple", "banana", "cherry");
  12. Collections.sort(list, comparator2);
  13. System.out.println(list); // 输出:[apple, banana, cherry]

8.1.2 方法引用

方法引用是Lambda表达式的一种简洁语法,用于直接引用现有的方法或构造函数。

四种方法引用类型

  1. 静态方法引用:ClassName::staticMethodName
  2. 实例方法引用:instance::instanceMethodName
  3. 对象的任意实例的方法引用:ClassName::instanceMethodName
  4. 构造函数引用:ClassName::new

示例

  1. // 使用静态方法引用
  2. Function<String, Integer> parseInt = Integer::parseInt;
  3. Integer num = parseInt.apply("123");
  4. System.out.println(num); // 输出:123
  5. // 使用实例方法引用
  6. String str = "Hello, World!";
  7. Supplier<Integer> stringLength = str::length;
  8. System.out.println(stringLength.get()); // 输出:13
  9. // 使用构造函数引用
  10. Supplier<List<String>> listSupplier = ArrayList::new;
  11. List<String> list = listSupplier.get();
  12. list.add("apple");
  13. System.out.println(list); // 输出:[apple]

8.2 Stream API:数据流处理

Stream API允许我们以声明式的方式对集合数据进行操作,如过滤、排序和聚合。

8.2.1 创建Stream

Stream可以通过集合、数组或生成函数创建。

示例

  1. // 从集合创建Stream
  2. List<String> list = Arrays.asList("apple", "banana", "cherry");
  3. Stream<String> stream1 = list.stream();
  4. // 从数组创建Stream
  5. String[] array = {"apple", "banana", "cherry"};
  6. Stream<String> stream2 = Arrays.stream(array);
  7. // 使用Stream生成函数
  8. Stream<String> stream3 = Stream.of("apple", "banana", "cherry");

8.2.2 常用操作

过滤(filter)

  1. List<String> fruits = Arrays.asList("apple", "banana", "cherry", "date");
  2. Stream<String> filteredFruits = fruits.stream()
  3. .filter(fruit -> fruit.startsWith("a"));
  4. filteredFruits.forEach(System.out::println); // 输出:apple

映射(map)

  1. List<String> fruits = Arrays.asList("apple", "banana", "cherry");
  2. Stream<Integer> fruitLengths = fruits.stream()
  3. .map(String::length);
  4. fruitLengths.forEach(System.out::println); // 输出:5, 6, 6

归约(reduce)

  1. List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
  2. int sum = numbers.stream()
  3. .reduce(0, Integer::sum);
  4. System.out.println(sum); // 输出:15

聚合操作

  1. List<String> fruits = Arrays.asList("apple", "banana", "cherry", "date");
  2. long count = fruits.stream()
  3. .filter(fruit -> fruit.length() > 5)
  4. .count();
  5. System.out.println(count); // 输出:2(banana和cherry)

8.3 Optional:优雅的空指针处理

Optional类是一个容器类,用于表示可能包含或不包含值的对象,通过显式地处理null值,避免空指针异常。

8.3.1 创建Optional对象

示例

  1. // 创建空的Optional
  2. Optional<String> empty = Optional.empty();
  3. // 使用非null值创建Optional
  4. Optional<String> nonEmpty = Optional.of("Hello");
  5. // 使用可能为null的值创建Optional
  6. Optional<String> nullable = Optional.ofNullable(null);

8.3.2 使用Optional对象

示例

  1. Optional<String> optional = Optional.of("Hello, World!");
  2. // 检查是否有值
  3. if (optional.isPresent()) {
  4. System.out.println(optional.get());
  5. }
  6. // 使用ifPresent进行消费
  7. optional.ifPresent(value -> System.out.println("Value: " + value));
  8. // 设置默认值
  9. String defaultValue = optional.orElse("Default Value");
  10. System.out.println(defaultValue); // 输出:Hello, World!
  11. // 使用orElseGet提供默认值
  12. String defaultValue2 = optional.orElseGet(() -> "Default Value");
  13. System.out.println(defaultValue2); // 输出:Hello, World!
  14. // 使用orElseThrow抛出异常
  15. String value = optional.orElseThrow(() -> new RuntimeException("Value is not present"));
  16. System.out.println(value); // 输出:Hello, World!

8.3.3 Optional的链式操作

示例

  1. Optional<String> optional = Optional.of("Hello, World!");
  2. // 链式操作
  3. optional.map(String::toUpperCase)
  4. .filter(value -> value.startsWith("HELLO"))
  5. .ifPresent(System.out::println); // 输出:HELLO, WORLD!