在完成对C语言的学习后,我最近开始了对C++和Java的学习,目前跟着视频学习了一些语法,也跟着敲了一些代码,有了一定的掌握程度。现在将跟着视频做的笔记进行整理。本篇博客是整理Java知识点的第三十二篇博客。
本篇博客介绍了Java的Lambda表达式和接口的组成。
本系列博客所有Java代码都使用IntelliJ IDEA编译运行,版本为2022.1。所用JDK版本为JDK11。
目录
Lambda表达式
体验Lambda表达式
面向对象思想强调通过对象的形式做事情。函数式思想则忽略面向对象的复杂语法,强调做什么,而不是以什么形式去做。Lambda表达式是函数式思想的体现。
public class lambdatest1 {
public static void main(String[] args){
new Thread(()->{
System.out.println("It has started!");
}).start();
}
}
程序使用了一个Lambda表达式,程序的输出是:
It has started!
Lambda表达式的标准格式
Lambda表达式的三要素是形式参数,箭头,代码块。格式是:
(形式参数) -> (代码块)
如果有多个形式参数,则参数之间用逗号隔开,没有参数就留空。
->代表指向动作
代码块是具体做的事情,就是以前写的方法体的内容。
Lambda表达式练习抽象方法无参无返回值
Lambda表达式使用前提:有一个接口,接口中只有一个抽象方法。
public interface lambda1A {
public void eat();
}
lambda1A接口有抽象方法eat,没有参数没有返回值。
public class lambda1B {
public static void main(String[] args){
eattest(()-> {
System.out.println("Hello lambda");
});
}
public static void eattest(lambda1A test){
test.eat();
}
}
lambda1B类有一个方法eattest,接受一个lambda1A的实现类,并执行其eat方法。main方法通过lambda表达式传参,表明eat方法输出Hello lambda。
程序的输出是:
Hello lambda
Lambda表达式练习抽象方法带参无返回值
public interface lambda2A {
public void fly(String s);
}
lambda2A接口有fly抽象方法,接受一个String类型的s,无返回值。
public class lambda2B {
public static void main(String[] args){
flyable((String s) -> {
System.out.println(s + " study how to fly");
});
}
public static void flyable(lambda2A test){
test.fly("bird");
}
}
lambda2B的flyable方法接受一个lambda2A的实现类对象,并调用其fly方法,传入bird作为参数。main方法使用了Lambda表达式。
程序的输出是:
bird study how to fly
Lambda表达式练习抽象方法带参带返回值
public interface lambda3A {
public int addable(int a,int b);
}
lambda3A的成员方法addable接受两个int类型变量,返回一个int类型值。
public class lambda3B {
public static void main(String[] args){
addtest((int x,int y) -> {
return x + y;
});
}
public static void addtest(lambda3A test){
int result = test.addable(10,15);
System.out.println(result);
}
}
lambda3B的方法addtest接受一个lambda3A的实现类,调用其addable方法并传入参数,随后输出得到的结果。main方法使用了lambda表达式。程序的输出是:
25
Lambda表达式的省略模式
参数类型可以省略,但是有多个参数时不能只省略一个。如果参数只有一个,那么小括号可以省略。如果代码块的语句只有一条,那么可以省略大括号和分号,甚至是return。
Lambda表达式的注意事项
使用Lambda表达式必须有接口,接口中必须只有一个抽象方法。
必须有上下文环境才能推导出Lambda对应的接口。
可以根据局部变量的赋值得知Lambda对应的接口。也可以根据调用方法的参数得知Lambda对应的接口。
Lambda表达式和匿名内部类的区别
匿名内部类可以是接口,可以是抽象类,也可以是具体类,但是Lambda表达式只能是接口。
如果接口中只有一个抽象方法,可以用Lambda表达式,也可以用匿名内部类。如果有多个抽象方法,那么只能用匿名内部类。
匿名内部类在编译后会产生一个单独的.class字节码文件,Lambda表达式没有,对应的字节码是运行时动态生成的。
接口的组成
接口的组成概述
在JDK8之前,接口只有常量(默认public static final修饰)和抽象方法(默认public abstract修饰)。JDK8中,接口可以有默认方法和静态方法,JDK9中,接口又可以有私有方法。
接口中的默认方法
接口中默认方法的格式是:
public default 返回值类型 方法名(参数列表){...}
默认方法不是抽象方法,因此不强制被重写,可以被重写,重写时去掉default关键字。public可以省略,default不能省略。
public interface defaultinterface {
public abstract void show1();
public abstract void show2();
public default void show3(){
System.out.println("show3");
}
}
这是defaultinterface接口,其中show1和show2是抽象方法,show3是默认方法,有函数体。
public class defaulttest1 implements defaultinterface{
public void show1()
{
System.out.println("1.show1");
}
public void show2()
{
System.out.println("1.show2");
}
public void show3(){
System.out.println("1.show3");
}
}
defaulttest1类实现defaultinterface接口,将show1 show2和show3方法都重写。
public class defaulttest2 implements defaultinterface{
public void show1()
{
System.out.println("2.show1");
}
public void show2()
{
System.out.println("2.show2");
}
}
defaulttest2类实现了defaultinterface接口,将show1和show2方法重写,没有重写show3方法。
public class lambdatest2 {
public static void main(String[] args){
defaultinterface dt1 = new defaulttest1();
dt1.show1();
dt1.show2();
dt1.show3();
defaultinterface dt2 = new defaulttest2();
dt2.show1();
dt2.show2();
dt2.show3();
}
}
这是测试代码,程序的输出是:
1.show1
1.show2
1.show3
2.show1
2.show2
show3
接口中的静态方法
接口中静态方法的格式是:
public static 返回值类型 方法名 (参数列表){...}
接口中静态方法只能通过接口名调用,不能通过实现类名或者对象名调用。public可以省略,static不能省略。
public interface staticinterface {
public void test();
public static void show(){
System.out.println("Show");
}
}
staticinterface接口的test方法是抽象方法,show方法是静态方法。
public class staticinterfacetest implements staticinterface{
public void test(){
System.out.println("test");
}
}
staticinterfacetest类实现了staticinterface接口,实现test方法。
public class lambdatest3 {
public static void main(String[] args){
staticinterface si = new staticinterfacetest();
si.test();
staticinterface.show();
}
}
程序的输出是:
test
Show
接口中的私有方法
接口中的私有方法定义格式是:
private 返回值类型 方法名(参数列表){...}
private static 返回值类型 方法名(参数列表){...}
默认方法可以调用私有方法的静态方法和非静态方法。静态方法只能调用私有方法的静态方法。
public interface privateinterface {
public default void show1(){
System.out.println("1Begin");
show12();
System.out.println("1End");
}
public default void show2(){
System.out.println("2Begin");
show12();
System.out.println("2End");
}
private void show12(){
System.out.println("A");
System.out.println("B");
System.out.println("C");
}
public static void show3(){
System.out.println("3Begin");
show34();
System.out.println("3End");
}
public static void show4(){
System.out.println("4Begin");
show34();
System.out.println("4End");
}
private static void show34(){
System.out.println("A");
System.out.println("B");
System.out.println("C");
}
}
这是privateinterface接口,show1和show2方法是默认方法,show12是私有非静态方法。show3和show4方法是静态方法,show34方法是私有静态方法。show1和show2方法调用了show12方法(也可以调用show34方法)。show3和show4方法调用了show34方法(不可以调用show12方法)。
public class privateinterfacetest implements privateinterface{
}
这是privateinterfacetest类,实现了privateinterface接口,由于接口中没有必须实现的方法,因此无内容。
public class lambdatest4 {
public static void main(String[] args){
privateinterface pi = new privateinterfacetest();
pi.show1();
pi.show2();
privateinterface.show3();
privateinterface.show4();
}
}
这是程序的测试代码,程序的输出是:
1Begin
A
B
C
1End
2Begin
A
B
C
2End
3Begin
A
B
C
3End
4Begin
A
B
C
4End