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.of 和 Set.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.of 和 Set.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.compare 和 Int.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.compare 和 Long.compare 方法来比较两个整数和长整数值。
17. 引入 Double.compare 和 Float.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.compare 和 Float.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 编程更加高效和优雅。
