「这是我参与2022首次更文挑战的第2天,活动详情查看:2022首次更文挑战」
java8新特性
Java 8 (又称为 jdk 1.8) 是 Java 语言开发的一个主要版本。 Oracle 公司于 2014 年 3 月 18 日发布 Java 8 ,它支持函数式编程,新的 JavaScript 引擎,新的日期 API,新的Stream API 等。
Java 17 LTS is the latest long-term support release for the Java SE platform. JDK 17 binaries are free to use in production and free to redistribute, at no cost, under the Oracle No-Fee Terms and Conditions.
JDK 17 will receive updates under these terms, until at least September 2024.
Java 17 LTS 是 Java SE 平台的最新长期支持版本。
目前大多数企业开发使用最多的仍然是jdk8版本,所以作为一名java开发人员学习jdk8的新特性是很有必要的,可以让你的工作更高效。
新特性有哪些?
java8的新特性有很多,我们一起来学习其中的部分新特性吧。
首先我们查看自己电脑环境的jdk版本:
使用java -version命令,我的版本为1.8.0_211
$ java -version java version "1.8.0_211" Java(TM) SE Runtime Environment (build 1.8.0_211-b12) Java HotSpot(TM) 64-Bit Server VM (build 25.211-b12, mixed mode)
1.Lambda表达式
Lambda 表达式,也可称为闭包,它是推动 Java 8 发布的最重要新特性。
->操作符是Lambda操作符
左侧:Lambda表示式的参数列表 右侧:Lambda表达式中所要执行的功能
语法格式:
创建一个线程执行输出hello world,传统写法:
public static void main(String[] args) {
Runnable runnable = new Runnable() {
@Override
public void run() {
System.out.println("hello world");
}
};
Thread thread = new Thread(runnable);
thread.start();
}
lambda表达式写法:
public static void main(String[] args) {
Thread thread = new Thread(()->{
System.out.println("hello world");
});
thread.start();
}
为什么Runnable允许这样写,因为接口只有一个run方法,无参数,无返回值
- 无参数无返回值
创建一个Test接口,声明一个doSomething方法无参无返回值
public interface Test {
void doSomething();
}
测试一下:
public static void main(String[] args) {
Test test = ()->{
System.out.println("say hello");
};
test.doSomething();
}
输出结果:
say hello
- 有一个参数无返回值
创建一个Test2接口,声明一个doSomething方法有一个参数无返回值
public interface Test2 {
void doSomething(int a);
}
调用测试,只有一个参数()可以省略
Test2 test2 = (b)->{
System.out.println(b);
};
test2.doSomething(10);
输出结果:
10
- 多个参数无返回值
public interface Test2 {
void doSomething(int a,int b);
}
Test2 test2 = (a,b)->{
System.out.println(a+b);
};
test2.doSomething(10,20);
输出结果:
30
- 有返回值,使用
return返回结果
public interface Test2 {
int doSomething(int a,int b);
}
Test2 test2 = (a, b) -> {
return a + b;
};
System.out.println(test2.doSomething(10, 20));
lambda表达式的重要特征:
- **可选类型声明:**不需要声明参数类型,编译器可以统一识别参数值。
- **可选的参数圆括号:**一个参数无需定义圆括号,但多个参数需要定义圆括号。
- **可选的大括号:**如果主体包含了一个语句,就不需要使用大括号。
Test test = ()-> System.out.println("say hello");
- **可选的返回关键字:**如果主体只有一个表达式返回值则编译器会自动返回值,大括号需要指定表达式返回了一个数值。
lambda 表达式只能引用标记了 final 的外层局部变量,这就是说不能在 lambda 内部修改定义在域外的局部变量,否则会编译错误。
在局部如果修改编译器会检查报错,如果不修改,即使没有使用final修饰也不会报错。lambda 表达式的局部变量可以不用声明为 final,但是必须不可被后面的代码修改(即隐性的具有 final 的语义)。
在 Lambda 表达式当中不允许声明一个与局部变量同名的参数或者局部变量。
2.方法引用
方法引用通过方法的名字来指向一个方法。
方法引用可以使语言的构造更紧凑简洁,减少冗余代码。
方法引用使用一对冒号 ::
Test2 test2 = (a, b)->{
return a + b;
};
System.out.println(test2.doSomething(10, 20));
比如这里的return a+b,就可以使用Integer::sum,代码看起来更加简洁
Test2 test2 = Integer :: sum;
System.out.println(test2.doSomething(10, 20));
3.函数式接口
函数式接口(Functional Interface)就是一个有且仅有一个抽象方法,但是可以有多个非抽象方法的接口。
函数式接口可以被隐式转换为 lambda 表达式。
Lambda 表达式和方法引用(实际上也可认为是Lambda表达式)上。
如定义了一个函数式接口如下:
@FunctionalInterface
public interface Test {
void doSomething();
}
那么我就可以使用下面这种方式实现doSomething函数
Test test = ()-> System.out.println("say hello");
函数式接口实例
-
Predicate
java.util.function.Predicate 接口定义了一个名叫 test 的抽象方法,它接受泛型 T 对象,并返回一个boolean值。在对类型 T进行断言判断时,可以使用这个接口。通常称为断言性接口 。
输出1-10以内的偶数
Predicate<Integer> pre = (num)-> num%2==0;
for (int i=1;i<=10;i++){
if(pre.test(i)){
System.out.println(i);
}
}
结果:
- Consumer
java.util.function.Consumer接口定义了一个名叫 accept 的抽象方法,它接受泛型T,没有返回值(void)。如果需要访问类型 T 的对象,并对其执行某些操作,可以使用这个接口,通常称为消费性接口。
使用Consumer实现集合遍历操作:
Consumer<List<String>> con = (list)->{
for (String s:list){
System.out.println(s);
}
};
List<String> list = new ArrayList<>();
list.add("hello");
list.add("world");
list.add("jcuser");
con.accept(list);
输出结果:
- Function
java.util.function.Function<T, R>接口定义了一个叫作apply的方法,它接受一个泛型T的对象,并返回一个泛型R的对象。如果需要定义一个Lambda,将输入的信息映射到输出,可以使用这个接口(比如提取苹果的重量,或把字符串映射为它的长度),通常称为功能性接口。
使用Function实现用户密码 Base64加密操作:
Function<String,String> fun =(password)-> Base64.getEncoder().encodeToString(password.getBytes());
System.out.println(fun.apply("jcuser"));
输出结果:
amN1c2Vy
- Supplier
java.util.function.Supplier接口定义了一个get的抽象方法,它没有参数,返回一个泛型T的对象,这类似于一个工厂方法,通常称为功能性接口。
使用Supplier创建学生对象
Supplier<Student> supplier = ()-> {
Student student = new Student();
student.setName("张三");
return student;
};
System.out.println(supplier.get());
}
以上就是今天的java8新特性学习实践,下期我们再一起学习其他特性吧,欢迎点赞评论发表看法观点。