Java 8 是 Java 语言发展中的一个重要里程碑,它引入了许多新的特性和改进,极大地提高了编程效率和代码可读性。以下将详细介绍 Java 8 的20个实用新特性,并通过实际案例进行深度解析。

1. Lambda 表达式

Lambda 表达式允许开发者用更简洁的代码来表示接口中的单个方法实现。以下是一个简单的例子:

List<String> strings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl");

strings.forEach(s -> System.out.println("Size of string: " + s.length()));

在这个例子中,forEach 方法使用 Lambda 表达式遍历列表,并打印每个字符串的长度。

2. Stream API

Stream API 提供了一种高效的方式来处理集合中的数据。以下是一个使用 Stream API 进行排序的例子:

List<String> sortedList = strings.stream()
    .filter(s -> !s.isEmpty())
    .sorted()
    .collect(Collectors.toList());

System.out.println(sortedList);

这个例子中,Stream API 被用来过滤掉空字符串,并对非空字符串进行排序。

3. 默认方法

默认方法允许在接口中添加具体实现,而无需实现类重写该方法。以下是一个使用默认方法的例子:

interface Vehicle {
    default void print() {
        System.out.println("I am a vehicle");
    }
}

class Car implements Vehicle {
}

Vehicle myCar = new Car();
myCar.print(); // 输出:I am a vehicle

在这个例子中,Vehicle 接口中的 print 方法是一个默认方法,所以不需要 Car 类重写它。

4. 方法引用

方法引用允许我们通过方法名称来引用现有方法的功能。以下是一个使用方法引用的例子:

BiPredicate<String, String> containsString = String::contains;
boolean r = containsString.test("Hello World", "World");
System.out.println(r); // 输出:true

这个例子中,我们使用方法引用来检查字符串是否包含另一个字符串。

5. Optional 类

Optional 类用于处理可能为 null 的对象,从而避免空指针异常。以下是一个使用 Optional 的例子:

Optional<String> name = Optional.ofNullable("John");
name.ifPresent(x -> System.out.println(x.length()));

在这个例子中,Optional 类确保了 name 变量在访问其长度之前不会为 null。

6. 新的日期和时间 API

Java 8 引入了新的日期和时间 API,如 java.time 包,它提供了一组新的日期和时间类。以下是一个使用新的日期和时间 API 的例子:

LocalDate date = LocalDate.now();
System.out.println("Current date: " + date);

LocalDateTime dateTime = LocalDateTime.now();
System.out.println("Current date and time: " + dateTime);

在这个例子中,我们使用新的日期和时间 API 来获取当前的日期和时间。

7. 完美替换 BigDecimal

Java 8 中的 BigDecimal 类被完全替换,提供了更好的性能和功能。以下是一个使用 BigDecimal 的例子:

BigDecimal value1 = new BigDecimal("0.0");
BigDecimal value2 = new BigDecimal("0.1");
System.out.println(value1.subtract(value2).compareTo(BigDecimal.ZERO)); // 输出:-1

在这个例子中,我们使用 BigDecimal 来执行精确的算术运算。

8. 接口静态默认方法

Java 8 允许接口中定义静态方法,这些方法可以直接通过接口名称调用。以下是一个使用接口静态方法的例子:

interface MathUtils {
    static int add(int a, int b) {
        return a + b;
    }
}

System.out.println(MathUtils.add(5, 10)); // 输出:15

在这个例子中,MathUtils 接口定义了一个静态方法 add,可以直接通过接口名称调用。

9. 接口私有方法

Java 8 允许接口中定义私有方法,这些方法可以在接口内部使用,但无法在实现类中使用。以下是一个使用接口私有方法的例子:

interface Formula {
    double calculate(int a);

    default double apply(int a) {
        return calculate(a) * 100;
    }

    private double compute(int a) {
        return a * 100;
    }
}

在这个例子中,Formula 接口定义了一个私有方法 compute,它可以在接口内部使用。

10. 引入 Nashorn JavaScript 引擎

Java 8 引入了 Nashorn JavaScript 引擎,允许开发者直接在 Java 程序中使用 JavaScript 代码。以下是一个使用 Nashorn JavaScript 引擎的例子:

ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn");
engine.eval("print('Hello World!');");

在这个例子中,我们使用 Nashorn JavaScript 引擎来执行 JavaScript 代码。

11. 引入 CompletableFuture

CompletableFuture 类提供了异步编程的能力,使我们可以更容易地处理复杂的并发任务。以下是一个使用 CompletableFuture 的例子:

public static void main(String[] args) {
    CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
        System.out.println("Running asynchronously");
    });

    future.join();
}

在这个例子中,我们使用 CompletableFuture 来执行异步任务。

12. 引入 OptionalDouble, OptionalInt, OptionalLong

这些类提供了与 Optional 类类似的功能,专门用于处理可能为空的数值类型。以下是一个使用 OptionalInt 的例子:

OptionalInt optionalInt = OptionalInt.of(1);
System.out.println("Is present: " + optionalInt.isPresent()); // 输出:true
System.out.println("Value: " + optionalInt.getAsInt()); // 输出:1

在这个例子中,我们使用 OptionalInt 来处理整数。

13. 引入 Map 接口的新的构造器方法

Java 8 中的 Map 接口添加了新的构造器方法,如 of, ofMap 等,使创建 Map 对象更加方便。以下是一个使用这些新构造器方法的例子:

Map<String, String> map = Map.of("one", "1", "two", "2", "three", "3");
System.out.println(map); // 输出:{one=1, three=3, two=2}

在这个例子中,我们使用 Map.of 方法来创建一个简单的 Map 对象。

14. 引入 List.of 和 Set.of

Java 8 引入了 List.ofSet.of 方法,使创建不可变列表和集合更加方便。以下是一个使用这些方法的例子:

List<String> list = List.of("one", "two", "three");
Set<String> set = Set.of("one", "two", "three");

System.out.println(list); // 输出:[one, two, three]
System.out.println(set); // 输出:[one, two, three]

在这个例子中,我们使用 List.ofSet.of 方法来创建不可变的列表和集合。

15. 引入 Map.Entry 接口的新构造器方法

Java 8 中的 Map.Entry 接口添加了新的构造器方法,如 entryOf,使创建 Map.Entry 对象更加方便。以下是一个使用这个方法的例子:

Map.Entry<String, String> entry = Map.entry("one", "1");
System.out.println(entry.getKey()); // 输出:one
System.out.println(entry.getValue()); // 输出:1

在这个例子中,我们使用 Map.entry 方法来创建一个 Map.Entry 对象。

16. 引入 Long.compareInt.compare

这些方法用于比较两个整数或长整数值,并返回 -1、0 或 1。以下是一个使用这些方法的例子:

int i = Int.compare(5, 10);
System.out.println(i); // 输出:-1

long l = Long.compare(5L, 10L);
System.out.println(l); // 输出:-1

在这个例子中,我们使用 Int.compareLong.compare 方法来比较两个整数和长整数值。

17. 引入 Double.compareFloat.compare

这些方法用于比较两个浮点数值,并返回 -1、0 或 1。以下是一个使用这些方法的例子:

int d = Double.compare(5.5, 10.5);
System.out.println(d); // 输出:-1

int f = Float.compare(5.5f, 10.5f);
System.out.println(f); // 输出:-1

在这个例子中,我们使用 Double.compareFloat.compare 方法来比较两个浮点数值。

18. 引入 IntSummaryStatistics

这个类用于统计整数集合的基本统计信息,如平均值、总和、最大值、最小值和计数。以下是一个使用 IntSummaryStatistics 的例子:

int[] numbers = {1, 2, 3, 4, 5};
IntSummaryStatistics stats = IntSummaryStatistics.of(numbers);
System.out.println("Count: " + stats.getCount());
System.out.println("Average: " + stats.getAverage());
System.out.println("Max: " + stats.getMax());
System.out.println("Min: " + stats.getMin());
System.out.println("Sum: " + stats.getSum());

在这个例子中,我们使用 IntSummaryStatistics 来统计整数集合的基本统计信息。

19. 引入 String.join 方法

这个方法用于将多个字符串连接成一个字符串,并指定分隔符。以下是一个使用 String.join 的例子:

List<String> strings = Arrays.asList("abc", "", "bc", "efg", "abcd", "", "jkl");
String joinedString = String.join(";", strings);
System.out.println(joinedString); // 输出:abc;;bc;efg;abcd;;jkl

在这个例子中,我们使用 String.join 方法将字符串列表连接成一个字符串,并使用分号作为分隔符。

20. 引入 OptionalInt, OptionalDouble, OptionalLong

这些类提供了与 Optional 类类似的功能,专门用于处理可能为空的数值类型。以下是一个使用 OptionalInt 的例子:

OptionalInt optionalInt = OptionalInt.of(1);
System.out.println("Is present: " + optionalInt.isPresent()); // 输出:true
System.out.println("Value: " + optionalInt.getAsInt()); // 输出:1

在这个例子中,我们使用 OptionalInt 来处理整数。

通过以上20个实用新特性的介绍和案例解析,相信你已经对 Java 8 的特性有了更深入的了解。掌握这些特性,将使你的 Java 编程更加高效和优雅。