java8新特性
Lambda表达式
这是 Java 8 最受关注的特性。它允许把函数作为一个方法的参数(函数作为参数传递进方法中)。
- 语法:(parameters) -> expression 或 (parameters) -> { statements; }
1 2 3 4 5 6 7 8 9 10
| new Thread(new Runnable() { @Override public void run() { System.out.println("Hello World"); } }).start();
new Thread(() -> System.out.println("Hello World")).start();
|
函数式接口
Lambda 表达式必须依赖于函数式接口。
- 定义:一个接口中有且仅有一个抽象方法(但可以有多个默认方法或静态方法)。
- 注解:@FunctionalInterface(可选,用于编译器检查)。
- 内置四大核心接口:
Predicate<T>:断言型(输入 T,返回 boolean)
Consumer<T>:消费型(输入 T,无返回)
Function<T, R>:函数型(输入 T,返回 R)
Supplier<T>:供给型(无输入,返回 T)
方法引用
方法引用是 Lambda 表达式的一种更简洁的写法,当 Lambda 体中只是调用一个已存在的方法时,可以使用。
- 符号:::
- 常见形式:
- 对象::实例方法名
- 类名::静态方法名
- 类名::实例方法名(比较特殊,如 String::length)
- 类名::new(构造器引用)
Stream API (流式处理)
这是 Java 8 处理集合(Collection)的利器,它借鉴了数据库查询语言和函数式语言的特点。
- 特点:Stream 不存储数据,不修改源数据,它是延迟执行的(惰性求值)。
- 操作步骤:
- 创建流:list.stream()
- 中间操作:filter (过滤)、map (映射/转换)、sorted (排序)、distinct (去重)
- 终止操作:collect (转回集合)、forEach (遍历)、count (统计)、reduce (归约)
1 2 3 4 5
| List<String> list = Arrays.asList("apple", "banana", "orange"); List<String> result = list.stream() .filter(s -> s.startsWith("a")) .map(String::toUpperCase) .collect(Collectors.toList());
|
Optional 类
为了解决令人头疼的 NullPointerException(空指针异常)。
案例方便理解
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
|
Collections.sort(names, new Comparator<String>() { @Override public int compare(String a, String b) { return b.compareTo(a); } });
names.sort((a, b) -> b.compareTo(a));
Predicate<Integer> isAdult = (age) -> age >= 18;
System.out.println(isAdult.test(20)); System.out.println(isAdult.test(15));
Function<String, Integer> stringToInt = (s) -> Integer.parseInt(s); Integer result = stringToInt.apply("123");
|
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
|
Function<String, Integer> lambda = s -> Integer.parseInt(s);
Function<String, Integer> methodRef = Integer::parseInt;
StringBuilder sb = new StringBuilder();
Consumer<String> lambda = s -> sb.append(s);
Consumer<String> methodRef = sb::append;
Function<String, Integer> lambda = s -> s.length();
Function<String, Integer> methodRef = String::length;
Supplier<List<String>> listLambda = () -> new ArrayList<>();
Supplier<List<String>> listRef = 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 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
|
class User { String name; int age; String city; }
List<User> users = ...
List<String> beijingUserNames = users.stream() .filter(u -> "北京".equals(u.getCity())) .map(User::getName) .collect(Collectors.toList());
double avgAge = users.stream() .mapToInt(User::getAge) .average() .orElse(0.0);
Map<String, List<User>> usersByCity = users.stream() .collect(Collectors.groupingBy(User::getCity));
List<String> top3Names = users.stream() .sorted(Comparator.comparingInt(User::getAge).reversed()) .map(User::getName) .distinct() .limit(3) .collect(Collectors.toList());
List<String> allTags = users.stream() .flatMap(u -> u.getTags().stream()) .distinct() .collect(Collectors.toList());
|