Java8新特性

1.lambda表达式

Lambda 表达式是 Java 8 引入的一个重要特性,它提供了一种简洁、灵活的方式来编写函数式接口的实现代码。Lambda 表达式可以用来替代匿名内部类,使得代码更加简洁易读。

Lambda 表达式的基本语法如下:

		

		
(parameter list) -> {lambda body}

    
	
参数列表:Lambda 表达式可以有零个或多个参数,多个参数使用逗号分隔。参数的类型可以明确指定,也可以根据上下文自动推断。
箭头符号:箭头符号 -> 将参数列表和 Lambda 表达式的主体分隔开。
Lambda 主体:Lambda 表达式的主体可以是一个表达式,或者是一段代码块(使用大括号括起来)。如果主体是一个表达式,则可以自动推断返回值类型;如果主体是一个代码块,则需要使用 return 语句显式返回结果。
Lambda 表达式可以用在函数式接口的实现上,函数式接口是只有一个抽象方法的接口。Lambda 表达式简化了函数式接口的实现,可以在需要函数式接口的地方直接传递 Lambda 表达式作为参数。

下面是一些 Lambda 表达式的示例:

无参数的 Lambda 表达式:
		
java

		
Runnable runnable = () -> {
   System.out.println("Hello, Lambda!");
};

    
	
单个参数的 Lambda 表达式:
		
java

		
Consumer<String> consumer = (String message) -> {
   System.out.println("Message: " + message);
};

    
	
多个参数的 Lambda 表达式:
		
java

		
BiFunction<Integer, Integer, Integer> add = (Integer a, Integer b) -> {
   return a + b;
};

    
	
省略参数类型的 Lambda 表达式:
		
java

		
BiFunction<Integer, Integer, Integer> add = (a, b) -> {
   return a + b;
};

    
	
省略大括号和返回语句的 Lambda 表达式:
		
java

		
BiFunction<Integer, Integer, Integer> add = (a, b) -> a + b;

    
	
Lambda 表达式的使用可以大幅简化代码,使得代码更加简洁易读。但需要注意的是,Lambda 表达式只能用于函数式接口的实现,且函数式接口只能有一个抽象方法,否则会在编译时报错。

2.函数式接口

函数式接口是指只有一个抽象方法的接口。在 Java 中,可以使用 @FunctionalInterface 注解来标识一个接口是函数式接口,以确保该接口只有一个抽象方法。

函数式接口的类型可以用于 Lambda 表达式、方法引用和构造方法引用等场景,使得代码更加简洁和灵活。

下面是一些常见的函数式接口类型及其使用示例:

Runnable:表示一个没有参数和返回值的操作。
		
java

		
Runnable runnable = () -> {
   System.out.println("Hello, Lambda!");
};

    
	
Consumer<T>:表示接受一个参数并且没有返回值的操作。
		
java

		
Consumer<String> consumer = (String message) -> {
   System.out.println("Message: " + message);
};

    
	
Supplier<T>:表示一个不接受参数但返回一个结果的操作。
		
java

		
Supplier<Integer> supplier = () -> {
   return 42;
};

    
	
Function<T, R>:表示接受一个参数并返回一个结果的操作。
		
java

		
Function<Integer, String> function = (Integer number) -> {
   return "The number is: " + number;
};

    
	
Predicate<T>:表示接受一个参数并返回一个布尔值的操作。
		
java

		
Predicate<Integer> predicate = (Integer number) -> {
   return number > 0;
};

    
	
函数式接口类型可以在需要的地方使用,例如作为方法的参数或返回值类型,或者在 Lambda 表达式中进行实现。

		
java

		
public void doSomething(Runnable runnable) {
   runnable.run();
}

public String process(Function<Integer, String> function, int number) {
   return function.apply(number);
}

public boolean check(Predicate<Integer> predicate, int number) {
   return predicate.test(number);
}

// 使用示例
doSomething(() -> System.out.println("Hello, Lambda!"));

String result = process((Integer number) -> {
   return "The number is: " + number;
}, 42);

boolean isPositive = check((Integer number) -> {
   return number > 0;
}, -5);

3.stream流的方法具体使用

Stream 是 Java 8 引入的一个用于处理集合数据的 API,它提供了一种流式操作的方式,可以方便地对集合进行过滤、映射、排序、分组等操作。

Stream 的方法可以分为两类:中间操作和终端操作。

中间操作: 中间操作是指对流进行转换、过滤、映射等操作,可以链式调用多个中间操作。中间操作不会立即执行,只有在遇到终端操作时才会执行。
常用的中间操作方法包括:

filter(Predicate<T> predicate):根据指定的条件过滤流中的元素。
map(Function<T, R> mapper):将流中的元素进行映射转换。
sorted(Comparator<T> comparator):对流中的元素进行排序。
distinct():去除流中的重复元素。
limit(long maxSize):截取流中的前 N 个元素。
skip(long n):跳过流中的前 N 个元素。
示例:

		
java

		
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
List<Integer> filtered = numbers.stream()
                                .filter(n -> n % 2 == 0)
                                .collect(Collectors.toList());
// 结果:[2, 4]

    
	
终端操作: 终端操作是指对流进行最终的操作,如收集结果、遍历元素等。终端操作会触发流的执行,并产生最终的结果。
常用的终端操作方法包括:

collect(Collector<T, A, R> collector):将流中的元素收集到一个集合中。
forEach(Consumer<T> action):对流中的每个元素执行指定的操作。
count():返回流中元素的个数。
anyMatch(Predicate<T> predicate):判断流中是否存在满足指定条件的元素。
allMatch(Predicate<T> predicate):判断流中是否所有元素都满足指定条件。
noneMatch(Predicate<T> predicate):判断流中是否没有满足指定条件的元素。
示例:

		
java

		
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
long count = names.stream()
                  .filter(name -> name.length() > 4)
                  .count();
// 结果:2

    
	
Stream 提供了丰富的方法来处理集合数据,通过链式调用中间操作和终端操作,可以灵活地处理集合中的元素。通过使用 Stream,可以使代码更加简洁、可读性更高,并且可以充分利用多核处理器的并行能力来提高性能。

4.jdk8的时间api

在 JDK 8 中引入了新的时间和日期 API,用于替代旧的 java.util.Date 和 java.util.Calendar 类。新的时间和日期 API 提供了更加简洁、易用和线程安全的操作方式。

新的时间和日期 API 的主要类如下:

LocalDate:表示日期,不包含具体的时间和时区信息。
LocalTime:表示时间,不包含具体的日期和时区信息。
LocalDateTime:表示日期和时间,不包含时区信息。
Instant:表示时间戳,精确到纳秒级别。
Duration:表示时间间隔,可以用于计算两个时间点之间的差值。
Period:表示日期间隔,可以用于计算两个日期之间的差值。
ZoneId:表示时区。
ZonedDateTime:表示带时区的日期和时间。
使用新的时间和日期 API,可以进行各种时间和日期的操作,如创建日期、解析日期字符串、格式化日期、比较日期、计算日期间隔等。

下面是一些常用的示例:

创建日期和时间:
		
java

		
LocalDate date = LocalDate.now(); // 当前日期
LocalTime time = LocalTime.now(); // 当前时间
LocalDateTime dateTime = LocalDateTime.now(); // 当前日期和时间
Instant instant = Instant.now(); // 当前时间戳

    
	
解析日期字符串:
		
java

		
LocalDate date = LocalDate.parse("2022-01-01");
LocalTime time = LocalTime.parse("10:30:00");
LocalDateTime dateTime = LocalDateTime.parse("2022-01-01T10:30:00");

    
	
格式化日期和时间:
		
java

		
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
String formattedDateTime = dateTime.format(formatter);

    
	
比较日期和时间:
		
java

		
LocalDate date1 = LocalDate.of(2022, 1, 1);
LocalDate date2 = LocalDate.of(2022, 2, 1);
boolean isBefore = date1.isBefore(date2);
boolean isAfter = date1.isAfter(date2);

    
	
计算日期间隔:
		
java

		
LocalDate date1 = LocalDate.of(2022, 1, 1);
LocalDate date2 = LocalDate.of(2022, 2, 1);
Period period = Period.between(date1, date2);
int days = period.getDays();

    
	
转换时区:
		
java

		
ZoneId zoneId1 = ZoneId.of("Asia/Shanghai");
ZoneId zoneId2 = ZoneId.of("America/New_York");
ZonedDateTime dateTime1 = ZonedDateTime.of(dateTime, zoneId1);
ZonedDateTime dateTime2 = dateTime1.withZoneSameInstant(zoneId2);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值