这几天研究了一下jdk8的新特性,给我的感觉要围绕Lambda表达式和函数式接口,然后将代码简化,变得优雅的一种处理方式。就目前来说,用得到的地方并不多,代
码虽然看起来优雅了,写得少了些,实际上准备的东西会多一些,然后就是能阅读性没有之前强,不过这些小问题只是前期不熟悉而已,写多了说不定就喜欢上了。
- Lambda表达式
- 函数式接口
- 方法引用
- Stream API
- default方法
- 新的时间API
一、lambda表达式
相信大家都用过内部匿名函数,通常为了在方法体内写入几行代码便要写很多准备工作,而且看起来很不优雅。
使用了lambda表达式之后,就变得更加优雅些,没有了枝叶,突出了重点,看到我们只关心的一部分。
下面是两个旧写法和lambda表达式的写法:
//匿名内部类的使用
Runnable tradition = new Runnable() {
@Override
public void run() {
System.out.println("tradition");
}
};
tradition.run();
//优雅的lambda表达式的使用
Runnable lambdaRunnable = () -> System.out.println("lambdaRunnable");
lambdaRunnable.run();
二、函数式接口
函数式接口必须具备以下两个特征:
1.具有唯一的抽象方法
2.有@FunctionalInterface注解修饰
注意:
1.接口内可以有静态方法、或者是default方法、或者是Object类的抽象方法
示例:
@FunctionalInterface
public interface FunctionalInterfaceTest
{
//抽象方法
int add(int a, int b);
//default方法
default int addOne(int a){
return a+1;
}
//Object的抽象方法
String toString();
//静态方法
static Object test(){
return new Integer(0);
}
}
PS:jdk内就有一堆函数式接口了。大家可以去查一下。
三、方法引用
给我的第一感觉是麻烦,限制较多,而且实际的作用也并不是大。
有几种形式:引用静态方法、引用对象方法、引用构造方法,还有一个是反射构建的,个人比较少用,不做介绍了。
首先是来一个接口Message
//具有泛型的接口
interface Message<P,R> {
R transFrom(P p);
}
//引用静态方法,相当于实现了接口Message的唯一的抽象方法tranform.
Message<String,Integer> message= Person::print;
Integer value = message.transFrom("999");
//使用对象方法,相当于实现了接口Message的唯一的抽象方法tranform.
String content = "jdk1.8";
Message <Integer,String> message1 = content::substring;
String result = message1.transFrom(1);
//在User类中找到一个参数对应为String,Integer的构造方法
BiFunction<String, Integer, User> biFunction = User::new;
User person = biFunction.apply("mengday", 28);
@Data
@Component
public class User {
Integer password;
String name;
public User(){
}
//引用方法就就是找到这个构造方法进行构造
public User(String name,Integer password)
{
this.name = name;
this.password = password;
}
}
总结一下:引用方法,用其他方法 来实现 接口中的方法。
四、Stream API
这是个好东西,特别是应用在集合类上面,集合的操作Stream API 基本都是可以,而且写起来很简洁,是使用lambda表达式操作的,看起来很舒服。
下面这篇写得特别好,我就不在这班门弄斧了。
https://www.ibm.com/developerworks/cn/java/j-lo-java8streamapi/
五、default方法
jdk1.8之前规定接口只允许有抽象方法,不允许有方法体。有一天该接口需要增加新的功能,该怎么办呢?在接口添加抽象方法,然后在实现类中在实现?显然不现实,毕竟实现类有这么多。所以就推出了default方法可以在接口中写具体的方法体。
public interface A {
public default void a(){
System.out.println("这是A");
}
}
六、新的时间API
我想有新的time Api出现,就意味着旧的有他的缺陷。于是我查了一下,有这三个问题:非线程安全、设计复杂化、时区处理麻烦。这三个问题真的要命,相信也是各位的疼。
Java8的java.time包下有很多新的API处理时间,主要是这两个:Local、Zoned;
Local示例:
public static void main(String[] args) {
//获取当前的日期时间
LocalDateTime currentTime = LocalDateTime.now();
System.out.println("当前时间:" + currentTime);
LocalDate date1 = currentTime.toLocalDate();
System.out.println();
Month month = currentTime.getMonth();
int day = currentTime.getDayOfMonth();
int seconds = currentTime.getSecond();
System.out.println("月: " + month +", 日: " + day +", 秒: " + seconds);
// 12 december 2019
LocalDate date3 = LocalDate.of(2019, Month.DECEMBER, 12);
System.out.println("date3: " + date3);
// 15 小时 46 分钟
LocalTime date4 = LocalTime.of(15, 46);
System.out.println("date4: " + date4);
// 解析字符串
LocalTime date5 = LocalTime.parse("17:49:53");
System.out.println("date5: " + date5);
}
Zoned示例:
public static void main(String[] args) {
testZonedDateTime();
}
public static void testZonedDateTime(){
// 获取当前时间日期
ZonedDateTime date1 = ZonedDateTime.parse("2015-12-03T10:15:30+05:30[Asia/Shanghai]");
System.out.println("date1: " + date1);
ZoneId id = ZoneId.of("Europe/Paris");
System.out.println("ZoneId: " + id);
ZoneId currentZone = ZoneId.systemDefault();
System.out.println("当期时区: " + currentZone);
}