引言
Java 8是Java历史上最重要的版本之一。本文全面介绍Java 8的核心新特性。
一、Lambda表达式
1.1 基本语法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| Runnable r1 = new Runnable() { @Override public void run() { System.out.println("Hello"); } };
Runnable r2 = () -> System.out.println("Hello");
Comparator<Integer> comp = (a, b) -> a - b;
Comparator<Integer> comp2 = (a, b) -> { int result = a - b; return result; };
|
1.2 函数式接口
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| @FunctionalInterface interface MyFunction { int calculate(int a, int b); }
MyFunction add = (a, b) -> a + b; System.out.println(add.calculate(5, 3));
Function<String, Integer> parser = Integer::parseInt;
Predicate<String> isEmpty = String::isEmpty;
Consumer<String> printer = System.out::println;
Supplier<Double> random = Math::random;
|
二、Stream API
2.1 创建Stream
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| List<Integer> list = Arrays.asList(1, 2, 3, 4, 5); Stream<Integer> stream = list.stream();
int[] arr = {1, 2, 3}; IntStream intStream = Arrays.stream(arr);
Stream<String> stream2 = Stream.of("a", "b", "c");
Stream<Integer> iterate = Stream.iterate(0, n -> n + 1); Stream<Double> generate = Stream.generate(Math::random);
|
2.2 中间操作
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
| List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
numbers.stream() .filter(n -> n % 2 == 0) .forEach(System.out::println);
numbers.stream() .map(n -> n * 2) .forEach(System.out::println);
List<List<Integer>> lists = Arrays.asList( Arrays.asList(1, 2), Arrays.asList(3, 4) ); lists.stream() .flatMap(List::stream) .forEach(System.out::println);
Arrays.asList(1, 2, 2, 3, 3, 3) .stream() .distinct() .forEach(System.out::println);
numbers.stream() .sorted() .forEach(System.out::println);
numbers.stream() .limit(5) .forEach(System.out::println);
numbers.stream() .skip(5) .forEach(System.out::println);
|
2.3 终端操作
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
numbers.stream().forEach(System.out::println);
List<Integer> result = numbers.stream() .filter(n -> n > 2) .collect(Collectors.toList());
long count = numbers.stream().count();
int sum = numbers.stream().reduce(0, Integer::sum); int product = numbers.stream().reduce(1, (a, b) -> a * b);
Optional<Integer> min = numbers.stream().min(Integer::compare); Optional<Integer> max = numbers.stream().max(Integer::compare);
boolean hasEven = numbers.stream().anyMatch(n -> n % 2 == 0); boolean allPositive = numbers.stream().allMatch(n -> n > 0); boolean noneNegative = numbers.stream().noneMatch(n -> n < 0);
Optional<Integer> first = numbers.stream().findFirst(); Optional<Integer> any = numbers.stream().findAny();
|
2.4 Collectors收集器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| List<String> list = Arrays.asList("apple", "banana", "cherry");
List<String> result = list.stream().collect(Collectors.toList());
Set<String> set = list.stream().collect(Collectors.toSet());
Map<String, Integer> map = list.stream() .collect(Collectors.toMap(s -> s, String::length));
String joined = list.stream().collect(Collectors.joining(", "));
Map<Integer, List<String>> grouped = list.stream() .collect(Collectors.groupingBy(String::length));
Map<Boolean, List<String>> partitioned = list.stream() .collect(Collectors.partitioningBy(s -> s.length() > 5));
long count = list.stream().collect(Collectors.counting());
int totalLength = list.stream() .collect(Collectors.summingInt(String::length));
|
三、Optional类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| Optional<String> optional1 = Optional.of("Hello"); Optional<String> optional2 = Optional.ofNullable(null); Optional<String> optional3 = Optional.empty();
if (optional1.isPresent()) { System.out.println(optional1.get()); }
optional1.ifPresent(System.out::println);
String value = optional2.orElse("Default");
String value2 = optional2.orElseGet(() -> "Default");
String value3 = optional2.orElseThrow(() -> new RuntimeException("No value"));
Optional<Integer> length = optional1.map(String::length);
Optional<String> upper = optional1.flatMap(s -> Optional.of(s.toUpperCase()));
Optional<String> filtered = optional1.filter(s -> s.length() > 3);
|
四、方法引用
1 2 3 4 5 6 7 8 9 10 11 12 13
| Function<String, Integer> parser1 = Integer::parseInt;
String str = "Hello"; Supplier<Integer> supplier = str::length;
Function<String, Integer> function = String::length;
Supplier<List<String>> listSupplier = ArrayList::new; Function<Integer, List<String>> listFunction = ArrayList::new;
|
五、接口默认方法和静态方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| interface MyInterface { void abstractMethod(); default void defaultMethod() { System.out.println("Default method"); } static void staticMethod() { System.out.println("Static method"); } }
class MyClass implements MyInterface { @Override public void abstractMethod() { System.out.println("Abstract method implementation"); } }
MyClass obj = new MyClass(); obj.abstractMethod(); obj.defaultMethod(); MyInterface.staticMethod();
|
六、新的日期时间API
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| LocalDate date = LocalDate.now(); LocalDate birthday = LocalDate.of(1990, Month.JANUARY, 1);
LocalTime time = LocalTime.now(); LocalTime lunchTime = LocalTime.of(12, 30);
LocalDateTime datetime = LocalDateTime.now();
ZonedDateTime zonedDateTime = ZonedDateTime.now();
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); String formatted = datetime.format(formatter);
LocalDateTime parsed = LocalDateTime.parse("2022-08-22 13:20:00", formatter);
LocalDate tomorrow = date.plusDays(1); LocalDate lastWeek = date.minusWeeks(1);
Period period = Period.between(birthday, date); Duration duration = Duration.between(lunchTime, time);
|
总结
Java 8核心特性:
- Lambda表达式:简化代码
- Stream API:函数式数据处理
- Optional:避免空指针
- 方法引用:更简洁的Lambda
- 接口增强:默认方法和静态方法
- 新日期API:更好用的日期时间处理
参考资料