JDK1.8的新特性
一、Lambda表达式
Lambda表达式是JDK1.8引入的一种新语法,也是推动java8版本发展的最重要的一个更新。Lambda表达式可以理解为是一种匿名函数,简化了匿名内部类的使用,并提高代码的可读性和性能。Lambda表达式的基本语法: 接口/父类 引用名=(参数)->表达式。
Lambda表达式的特性:
-
简洁:将冗长的代码变的简单易读。
-
灵活:传递参数和返回值。
-
高效:提高代码性能,减少创建过多的中间对象。
//匿名
Add add1 = new Add(){
public void add(int a, int b) {
System.out.println(a+b);
};
};
add1.add(1,2);
//lambda
Add add2 = (a,b) -> System.out.println(a+b);
add2.add(1,2);
Java
二、接口增强(允许接口拥有方法体)
新的Interface接口中可以用default和static修饰。
default修饰的方法是普通实例方法,可以用this调用,可以被子类继承和重写
interface MyInterface {
default void myMethod() {
System.out.println("This is a default method.");
}
}
Java
static修饰的方法不能被子类继承
interface MyInterface {
//静态方法 可通过接口名直接调用
static void staticMethod() {
}
}
Java
三、函数式接口
函数式接口是只有一个抽象方法的接口,通常用于支持lambda表达式和函数式编程风格。函数式接口通常使用@FunctionalInterface
注解来标记判断其是否只包含一个抽象方法,主要是为了编译器检查和代码清晰度。
-
Java 8中常见的函数式接口如下:
1、自定义式函数式接口
@FunctionalInterface
public interface Add {
int add(int a, int b);
}
public static void main(String[] args) {
Add add = (int a, int b) -> a + b;
System.out.println(add.add(3, 4)); // 输出: 7
}
2、Predicate<T>:输入一个参数T,返回一个布尔值,可用于执行一些判断逻辑。
Predicate<String> isEmpty = s -> s.isEmpty();
System.out.println(isEmpty.test("")); // 输出: true
3、Function<T,R>:输入一个参数T,返回一个结果R,可用于执行一些转换逻辑。
Function<Integer, Integer> square = (Integer x) -> x * x;
System.out.println(square.apply(5)); // 输出: 25
Plain Text
4、Consumer<T>:消费型接口,输入一个参数T,表示消费掉这个参数,可用于执行一些操作但没有返回值。
5、Supplier<T>:供给型接口,返回一个数据T,可用于执行一些数据生成操作。
四、方法引用
方法引用可以理解为式Lambda表达式的一种语法糖,是Lambda表达式的简化形式,可以提高代码的可读性和简洁性。语法:类名::方法名
-
对象的实例方法引用 :object::methodName
-
类的静态方法引用:ClassName::staticMethodName
-
特定类型的实例方法引用:TypeName::methodName
-
构造器引用:ClassName::new
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
// 使用 lambda 表达式将每个字符串转换为大写
List<String> upperCaseNames = names.stream()
.map((String name) -> name.toUpperCase())
.collect(Collectors.toList());
//方法引用 引用String类型toUpperCase方法
List<String> upperCaseNames = names.stream()
.map(String::toUpperCase)
.collect(Collectors.toList());
五、Stream API
Stream API是一种抽象流,它是提供了一种新的处理数据的方式,可以对集合或数据元素进行函数式编程数据处理。
Stream操作核心点
源:数据源头,通常是集合、数组或其他支持迭代的数据结构--->
中间操作:执行Stream操作中的方法,操作返回新的Stream--->
终止操作:一旦执行,会使Stream被消费并产生结果。
// 使用 map() 方法和 String::toUpperCase 方法引用将所有字符串转换为大写
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
List<String> upperCaseNames = names.stream().map(String::toUpperCase).collect(Collectors.toList())
;
Stream API 的主要特征
-
惰性求值:中间操作(如
filter()
,map()
,sorted()
等)不会立即执行,而是在遇到终止操作时才开始执行。 -
管道化:多个中间操作可以串联起来形成一个管道,这样可以连续地对数据进行处理。
-
并行处理:可以通过简单地调用
parallel()
方法将 Stream 转换为并行 Stream,从而利用多核 CPU 的优势。 -
函数式编程:使用 Lambda 表达式和方法引用来定义 Stream 的操作,这使得代码更加简洁和易于理解。
java.util.stream常用方法
//filter(Predicate<? super T> predicate):过滤
list.stream().filter(s -> s.startsWith("a"));
//map(Function<? super T, ? extends U> mapper):元素转换
list.stream().map(String::toUpperCase)
//sorted 排序
list.stream().sorted();
//distinct():去除重复元素。
list.stream().distinct();
//limit(maxSize):限制 Stream 中元素的最大数量。
list.stream().limit();
//boolean allMatch(Predicate<? super T> predicate) 此流的所有元素是否与提供的predicate匹配。
list.stream().allMatch();
//skip(long n) 跳过前面n个元素
list.stream().skip();
//使用Collector对流进行归纳
list.stream().collect(Collector.toList())
//count统计Stream元素数量
list.stream().count()
//forEach遍历Stream所有元素
list.stream().ForEach();
//max(Comparator<? super T> comparator)查找最大值
list.stream().max();
//返回一个包含此流的元素的数组 toArray();
list.stream().toArray();
//findFirst() 和 findAny():查找第一个元素或任意元素(在并行流中)
list.stream().findFirst();
list.stream().parallelStream().findAny();
六、Optional类
Optional是一个工具类,可以是一个为null的容器对象,它的主要作用就是为了避免null值异常,防止NullpointException。
Optional常用方法
// 创建一个可能为null的字符串
String s1 = null;
String s2="hello";
// 使用Optional.ofNullable()来创建Optional对象
Optional<String> optionalString = Optional.ofNullable(s1);
Optional<String> optionalString2 = Optional.ofNullable(s2);
// 使用ifPresent()方法处理Optional中的值
optionalString.ifPresent(s -> System.out.println("Value: " + s));
optionalString2.ifPresent(s -> System.out.println("Value: " + s));
Person person = new Person();
//正常
if (ObjectUtil.isNotNull(person)){
System.out.println(person.getName());
}
//Optional处理空值
Optional.ofNullable(person).map(o->o.getName()).ifPresent(o-> System.out.println(o));
Java
七、新的日期和时间API
Java 8引入了全新的日期和时间API, 通过引入 java.time
包来提供一套更为强大、线程安全且易于使用的日期和时间 API。 对原有的java.util.Date
和java.util.Calendar
进行了重新设计和扩展。新的日期和时间API设计上比较简洁,同时也提供了许多方便的日期处理方法和函数。
常见的时间和日期类型:
-
LocalDate:表示年月日。
-
LocalTime:表示时分秒。
-
LocalDateTime:表示日期和时间。
-
Duration:表示两个时间之间的持续时间。
-
Period:表示两个日期之间的时间间隔。
Java 8中常见的日期和时间方法
-
plusDays:增加指定的天数。
-
minusDays:减少指定的天数。
-
withYear:设置年份。
Java8实现日期计算和格式化
//获取当前时间
LocalDateTime time=LocalDateTime.now();
System.out.println(time);
//减少指定天数
LocalDateTime yesterday = time.minusDays(1);
System.out.println(yesterday);
//通过DateTimeFormatter设置需转换的格式
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
String formattedTime = yesterday.format(formatter);
System.out.println(formattedTime);
https://javaguide.cn/java/new-features/java8-common-new-features.html#interface