一、Lambda 表达式
-
基本概念
- Lambda 表达式是一种匿名函数,可以简洁地表示可传递给方法或存储在变量中的代码块。它的语法形式为
(parameters) -> expression或(parameters) ->{ statements; }。例如,(int a, int b) -> a + b表示一个接收两个整数参数并返回它们之和的 Lambda 表达式。 - 这种表达式主要用于替代匿名内部类,使代码更加简洁明了。例如,在使用
Runnable接口时,传统方式是创建匿名内部类:
- Lambda 表达式是一种匿名函数,可以简洁地表示可传递给方法或存储在变量中的代码块。它的语法形式为
new Runnable() {
@Override
public void run() {
System.out.println("Hello from anonymous inner class");
}
};
- 用 Lambda 表达式可写成:
() -> System.out.println("Hello from Lambda");,运行结果会输出 "Hello from Lambda"。 - 再如,对于
Comparator接口,传统比较两个字符串长度的匿名内部类写法:
Comparator<String> comparator = new Comparator<String>() {
@Override
public int compare(String s1, String s2) {
return s1.length() - s2.length();
}
};
-
用 Lambda 表达式则为:
Comparator<String> comparator = (s1, s2) -> s1.length() - s2.length();。若有List<String> strings = Arrays.asList("apple", "banana", "cherry");,使用strings.sort(comparator);后,列表会按照字符串长度升序排序,结果为 ["apple", "cherry", "banana"]。
-
函数式接口
- Lambda 表达式与函数式接口密切相关。函数式接口是只包含一个抽象方法的接口,例如
java.util.function包中的Consumer<T>接口,它的抽象方法是void accept(T t)。可以这样使用:
- Lambda 表达式与函数式接口密切相关。函数式接口是只包含一个抽象方法的接口,例如
Consumer<String> printer = s -> System.out.println(s);
printer.accept("Hello");
// 输出 "Hello"
- 还有
Function<T, R>接口,用于将一种类型转换为另一种类型,抽象方法是R apply(T t)。例如,将字符串转换为整数长度:
Function<String, Integer> stringLength = s -> s.length();
int length = stringLength.apply("Java 8");
// length 的值为 6
- 又如
Predicate<T>接口,用于判断条件,抽象方法boolean test(T t)。比如判断一个整数是否为偶数:
Predicate<Integer> isEven = n -> n % 2 == 0;
boolean result = isEven.test(4);
// result 为 true
二、Stream API
-
创建 Stream
- 可以从集合、数组等多种数据源创建 Stream。例如,从
List创建:
- 可以从集合、数组等多种数据源创建 Stream。例如,从
List<Integer> numbers = Arrays.asList(1, 2, 3);
Stream<Integer> numberStream = numbers.stream();
-
也可以从数组创建,如
int[] intArray = {1, 2, 3}; IntStream intStream = Arrays.stream(intArray);。 -
还能通过
Stream.of()方法创建,如Stream<String> stringStream = Stream.of("a", "b", "c");。
-
中间操作和终端操作
- 中间操作包括过滤(
filter)、映射(map)等。过滤可以筛选出符合条件的元素,如:
- 中间操作包括过滤(
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
List<Integer> filteredNumbers = numbers.stream().filter(n -> n > 1).collect(Collectors.toList());
// filteredNumbers 结果为 [2, 3, 4, 5]
- 映射用于转换元素类型,如:
List<Integer> numbers = Arrays.asList(1, 2, 3);
List<Integer> mappedNumbers = numbers.stream().map(n -> n * 2).collect(Collectors.toList());
// mappedNumbers 结果为 [2, 4, 6]
- 排序(
sorted)操作,如:
List<Integer> numbers = Arrays.asList(3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5);
List<Integer> sortedNumbers = numbers.stream().sorted().collect(Collectors.toList());
// sortedNumbers 结果为 [1, 1, 2, 3, 3, 4, 5, 5, 5, 6, 9]
- 终端操作如收集(
collect)用于将结果收集到集合中,还有匹配(anyMatch、allMatch、noneMatch)、计数(count)等操作。例如:
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
boolean anyEven = numbers.stream().anyMatch(n -> n % 2 == 0);
// anyEven 为 true
boolean allEven = numbers.stream().allMatch(n -> n % 2 == 0);
// allEven 为 false
boolean noneEven = numbers.stream().noneMatch(n -> n % 2 == 0);
// noneEven 为 false
long count = numbers.stream().count();
// count 为 5
三、接口的默认方法和静态方法
-
默认方法
- 接口可以有默认方法,通过
default关键字定义。例如,在一个接口MyInterface中:
- 接口可以有默认方法,通过
public interface MyInterface {
default void myDefaultMethod() {
System.out.println("This is a default method");
}
}
- 实现类可以不实现默认方法,直接调用接口的默认方法。这主要用于在接口中添加新方法而不破坏现有实现类。例如:
class MyClass implements MyInterface {
// 无需实现 myDefaultMethod
}
MyClass myClass = new MyClass();
myClass.myDefaultMethod();
// 输出 "This is a default method"
-
静态方法
- 接口也可以有静态方法,使用
static关键字。例如:
- 接口也可以有静态方法,使用
public interface MyInterface {
static void myStaticMethod() {
System.out.println("This is a static method");
}
}
- 静态方法可以直接通过接口名调用,如
MyInterface.myStaticMethod();,输出 "This is a static method"。
四、新的日期和时间 API
-
LocalDate、LocalTime和LocalDateTimeLocalDate表示日期,例如获取当前日期:
LocalDate now = LocalDate.now();
// 假设当前日期是 2024-05-01,now 的值就是 2024-05-01
-
可以进行日期的比较、加减等操作,如
LocalDate tomorrow = now.plusDays(1);,tomorrow的值为 2024-05-02。 -
LocalTime表示时间,LocalDateTime则表示日期和时间。例如,LocalTime time = LocalTime.now();获取当前时间,LocalDateTime dateTime = LocalDateTime.now();获取当前日期和时间。
-
日期格式化和解析
- 使用
DateTimeFormatter进行日期格式化和解析。例如,格式化日期:
- 使用
LocalDate date = LocalDate.now();
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy - MM - dd");
String formattedDate = date.format(formatter);
// 假设当前日期是 2024-05-01,formattedDate 的值就是 "2024 - 05 - 01"
- 解析日期:
String dateString = "2024 - 05 - 01";
DateTimeFormatter parser = DateTimeFormatter.ofPattern("yyyy - MM - dd");
LocalDate parsedDate = LocalDate.parse(dateString, parser);
// parsedDate 的值为 2024-05-01