new Thread (()-> System.out.("abc")).start());等价于new Thread(new Runnable() {@Override public void run() {System.out.println("abc");} }).start();
import java.util.ArrayList;
public class Main {
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
list.add("a");
list.add("b");
list.add("c");
list.forEach(System.out::println);
}
}
等价于
import java.util.ArrayList;
public class Main {
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
list.add("a");
list.add("b");
list.add("c");
list.forEach(item -> System.out.println(item));
}
}
上例中我们将 System.out::println 方法作为静态方法来引用。
3. 函数式接口
有且仅有一个抽象方法的接口叫做函数式接口,函数式接口可以被隐式转换为 Lambda 表达式。通常函数式接口 上会添加@FunctionalInterface 注解。
4 .接口允许定义默认方法和静态方法 从 JDK8 开始,允许接口中存在一个或多个默认非抽象方法和静态方法
5 .Stream API
新添加的 StreamAPI(java.util.stream)把真正的函数式编程风格引入到 Java 中。这种风格将要处理的元素集 合看作一种流,流在管道中传输,并且可以在管道的节点上进行处理,比如筛选, 排序,聚合等
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class StreamExample {
public static void main(String[] args) {
// 创建一个字符串列表
List<String> words = Arrays.asList("apple", "banana", "cherry", "date", "fig", "grape");
// 使用Stream API进行处理
List<String> sortedWords = words.stream() // 转换成流
.filter(word -> word.startsWith("c")) // 筛选以"c"开头的单词
.sorted() // 排序
.collect(Collectors.toList()); // 收集结果
// 打印结果
sortedWords.forEach(System.out::println);
}
}
在这个例子中,我们首先创建了一个包含不同单词的List
。然后,我们对这个列表执行了以下操作:
stream()
:将列表转换成流,以便进行流式处理。filter()
:使用一个Lambda表达式筛选出以"c"开头的单词。sorted()
:对筛选后的流中的元素进行自然排序。collect()
:将流中的元素收集到一个新的列表中。
最后,我们使用forEach()
方法和方法引用System.out::println
来打印出排序后的结果。
这个例子展示了Stream API
如何以一种声明式和函数式的方式处理集合数据。通过管道化的操作,我们可以对数据流进行复杂的处理,而不必编写复杂的循环和条件逻辑。
6 .日期/时间类改进
之前的 JDK 自带的日期处理类非常不方便,我们处理的时候经常是使用的第三方 工具包,比如 commons-lang 包等。不过 JDK8 出现之后这个改观了很多,比如日期时间的创建、比较、调整、 格式化、时间间隔等。 这些类都在 java.time 包下,LocalDate/LocalTime/LocalDateTime
7 Optional 类
Optional 类是一个可以为 null 的容器对象。如果值存在则 isPresent()方法会返 回 true,调用 get()方法会返回该对象。
import java.util.Optional;
public class OptionalExample {
public static void main(String[] args) {
// 使用 Optional.of 创建一个 Optional 实例,参数不能为 null
Optional<String> optionalNonNull = Optional.of("Kimi");
// 使用 Optional.ofNullable 创建一个 Optional 实例,参数可以为 null
Optional<String> optionalNullable = Optional.ofNullable(null);
// 使用 isPresent() 检查值是否存在
System.out.println("Value is present (non-null): " + optionalNonNull.isPresent());
System.out.println("Value is present (nullable): " + optionalNullable.isPresent());
// 使用 get() 获取 Optional 实例中的值,如果实例为 null 会抛出 NoSuchElementException
try {
String valueNonNull = optionalNonNull.get();
System.out.println("Value (non-null): " + valueNonNull);
} catch (NoSuchElementException e) {
System.out.println("No value present (non-null)");
}
// 使用 orElse() 提供一个备用值,如果 Optional 实例为 null 则返回备用值
String valueNullable = optionalNullable.orElse("Default Value");
System.out.println("Value or default (nullable): " + valueNullable);
// 使用 ifPresent() 执行一个操作,如果值存在则执行
optionalNonNull.ifPresent(value -> System.out.println("Value is: " + value));
}
}
在这个例子中:
- 我们使用
Optional.of("Kimi")
创建了一个非空的Optional
实例。 - 使用
Optional.ofNullable(null)
创建了一个可能为空的Optional
实例。 - 我们用
isPresent()
方法检查Optional
实例是否包含一个非空值。 - 尝试用
get()
方法获取Optional
中的值,如果值不存在(即Optional
是空的),会抛出NoSuchElementException
。 - 使用
orElse("Default Value")
方法提供了一个备用值,如果Optional
是空的,则返回这个备用值。 - 使用
ifPresent(value -> ...)
方法来执行一个操作,这个操作只有在Optional
实例包含一个非空值时才会执行。
使用 Optional
类可以避免显式地检查 null
,使代码更加清晰和安全。
8 Java8Base64 实现 Java 8 内置了 Base64 编码的编码器和解码器