Java8新特性:方法引用详解-java技术

  • 时间:
  • 浏览:192
  • 来源:恰卡网
Java大联盟

致力于最高效的Java学习

关注

Java8 引入了方法引用特性,使用它可以简化 Lambda 表达式,我们知道 Lambda 是用来替代匿名类的,即使用 Lambda 可以更加方便地实现函数接口的方法,如下所示。

1、自定义函数接口

publicinterfaceMyInterface{publicvoidtest(intnum);}

2、接口调用

publicclassTest{publicstaticvoidmain(String[]args){test(10,(num)->{num++;System.out.println(num);});}publicstaticvoidtest(intnum,MyInterfacemyInterface){myInterface.test(num);}}

在这个案例中

(num)->{num++;System.out.println(num);})

上面这段代码就是对 MyInterface 接口 test(int num) 方法的具体实现,如果 test(int num) 方法只需要调用 System.out.println(num); 而不需要添加额外的逻辑代码,可以这样写,省略 {}。

test(10,(num)->System.out.println(num));

如果还觉得不够简化,可以使用方法引用进一步简化代码,如下所示。

test(10,System.out::println);

System.out::println 就是方法引用,表示调用 System.out 的 println 方法,方法引用提供了一种引用而不执行方法的方式,它需要由兼容的函数式接口构成的目标类型上下文,执行时方法引用会自动创建函数式接口的一个实例。

简单来说,方法引用本身就是一个 Lambda 表达式,它是一种更加简洁、易读的 Lambda 表达式,通过双冒号 :: 来引用目标方法。

方法引用是用来简化 Lambda 表达式的,因为在某些特定场景下,Lambda 表达式可能只需要调用一个已存在的方法,而不做其他任何逻辑处理,针对这种情况,通过一个方法名字来引用这个已存在的方法会使得代码结构更加清晰,这就是方法引用的底层逻辑。

方法引用的具体操作形式有以下四种:

1、引用目标类的静态方法。

2、引用目标对象的实例方法。

3、引用目标类的构造方法。

4、引用目标类型任意对象的实例方法。

接下来我们分别做演示。

引用目标类的静态方法

1、自定义函数接口。

publicinterfaceMyInterface{publicvoidtest();}

2、自定义一个类,提供静态方法。

publicclassMyDemo{publicstaticvoidstaticTest(){System.out.println("staticTest...");}}

3、测试类如下所示,我们分别用匿名类、Lambda 表达式、方法引用 3 种方式来实现,方便大家做对比,从匿名类简化到 Lambda 表达式,再简化到方法引用的过程。

publicclassTest{publicstaticvoidmain(String[]args){//1、匿名类test(newMyInterface(){@Overridepublicvoidtest(){MyDemo.staticTest();}});//2、Lambda表达式test(()->MyDemo.staticTest());//3、方法引用test(MyDemo::staticTest);}publicstaticvoidtest(MyInterfacemyInterface){myInterface.test();}}

4、运行结果如下图所示。

引用目标对象的实例方法

1、自定义函数接口。

publicinterfaceMyInterface{publicvoidtest(MyDemomyDemo);}

2、自定义一个类,提供实例方法。

publicclassMyDemo{publicvoidinstanceTest(){System.out.println("instanceTest...");}}

3、测试类如下所示。

publicclassTest{publicstaticvoidmain(String[]args){//1、匿名类test(newMyDemo(),newMyInterface(){@Overridepublicvoidtest(MyDemomyDemo){myDemo.instanceTest();}});//2、Lambda表达式test(newMyDemo(),(myDemo)->myDemo.instanceTest());//3、方法引用test(newMyDemo(),MyDemo::instanceTest);}publicstaticvoidtest(MyDemomyDemo,MyInterfacemyInterface){myInterface.test(myDemo);}}

4、运行结果如下图所示。

引用目标类的构造方法

1、自定义函数接口。

publicinterfaceMyInterface{publicMyDemotest();}

2、自定义一个类,提供构造方法,使用默认的无参构造。

publicclassMyDemo{}

3、测试类如下所示。

publicclassTest{publicstaticvoidmain(String[]args){//1、匿名类test(newMyInterface(){@OverridepublicMyDemotest(){returnnewMyDemo();}});//2、Lambda表达式test(()->newMyDemo());//3、方法引用test(MyDemo::new);}publicstaticvoidtest(MyInterfacemyInterface){System.out.println(myInterface.test());}}

4、运行结果如下图所示。

引用目标类型任意对象的实例方法

1、自定义函数接口。

publicinterfaceMyInterface{publicbooleantest(MyDemomyDemo1,MyDemomyDemo2);}

2、自定义一个类,提供 compare 方法,逻辑很简单,通过两个实例对象的 num 值判断大小。

publicclassMyDemo{privateIntegernum;publicIntegergetNum(){returnnum;}publicMyDemo(Integernum){this.num=num;}publicbooleancompare(MyDemomyDemo){if(this.num>myDemo.getNum()){returntrue;}returnfalse;}}

3、测试类如下所示。

publicclassTest{publicstaticvoidmain(String[]args){//1、匿名类test(newMyDemo(2),newMyDemo(1),newMyInterface(){@Overridepublicbooleantest(MyDemomyDemo1,MyDemomyDemo2){returnmyDemo1.compare(myDemo2);}});//2、Lambda表达式test(newMyDemo(2),newMyDemo(1),(MyDemomyDemo1,MyDemomyDemo2)->myDemo1.compare(myDemo2));//3、方法引用test(newMyDemo(2),newMyDemo(1),MyDemo::compare);}publicstaticvoidtest(MyDemomyDemo1,MyDemomyDemo2,MyInterfacemyInterface){System.out.println(myInterface.test(myDemo1,myDemo2));}}

4、运行结果如下图所示。

实际案例

看到这里,想必你已经对方法引用的概念和具体操作有了一定的了解,接下来我们通过两个实际案例来帮助大家更好的掌握方法引用的使用。

案例1:对 Integer 数组进行排序

1、使用 Lambda 表达式的操作如下所示。

publicclassTest{publicstaticvoidmain(String[]args){Integer[]array={1,6,2,3,5,4};Arrays.sort(array,(num1,num2)->num1.compareTo(num2));System.out.println(Arrays.asList(array));}}

2、使用方法引用的操作如下所示。

publicclassTest{publicstaticvoidmain(String[]args){Integer[]array={1,6,2,3,5,4};Arrays.sort(array,Integer::compareTo);System.out.println(Arrays.asList(array));}}

3、运行结果如下图所示

案例2:根据年龄对自定义数据类型 Student 进行排序

1、自定义 Student,定义根据年龄进行排序的方法。

publicclassStudent{privateLongid;privateStringname;privateIntegerage;publicIntegergetAge(){returnage;}publicStudent(Longid,Stringname,Integerage){this.id=id;this.name=name;this.age=age;}@OverridepublicStringtoString(){return"Student{"+"id="+id+",name='"+name+'''+",age="+age+'}';}publicintcompareByAge(Studentstudent){returnthis.age.compareTo(student.getAge());}}

2、使用 Lambda 表达式的操作如下所示。

publicclassTest{publicstaticvoidmain(String[]args){Student[]array={newStudent(1L,"张三",33),newStudent(2L,"李四",22),newStudent(3L,"王五",18),newStudent(4L,"小明",26),newStudent(5L,"小红",19),newStudent(6L,"小黑",28),};Arrays.sort(array,(stu1,stu2)->stu1.compareByAge(stu2));for(Studentstudent:array){System.out.println(student);}}}

3、使用方法引用的操作如下所示。

publicclassTest{publicstaticvoidmain(String[]args){Student[]array={newStudent(1L,"张三",33),newStudent(2L,"李四",22),newStudent(3L,"王五",18),newStudent(4L,"小明",26),newStudent(5L,"小红",19),newStudent(6L,"小黑",28),};Arrays.sort(array,Student::compareByAge);for(Studentstudent:array){System.out.println(student);}}}

4、运行结果如下图所示。

【框架合集】SpringMVC教程汇总

【框架合集】MyBatis教程汇总

【框架合集】Spring教程汇总

【框架整合】SSM教程

【十套项目源码】

【BAT面试真题】

猜你喜欢

Java8中的流操作-基本使用&性能测试-java技术

一、流(Stream)简介流是Java8中API的新成员,它允许你以声明式的方式处理数据集合(通过查询语句来表达,而不是临时编写一个实现)。这有点儿像是我们操作数据库一样,例如

2019-08-20

Java8中的流操作-基本使用&性能测试-java技术

一、流(Stream)简介流是Java8中API的新成员,它允许你以声明式的方式处理数据集合(通过查询语句来表达,而不是临时编写一个实现)。这有点儿像是我们操作数据库一样,例如

2019-08-20

Java8新特性:方法引用详解-java技术

Java大联盟致力于最高效的Java学习关注Java8引入了方法引用特性,使用它可以简化Lambda表达式,我们知道Lambda是用来替代匿名类的,即使用Lambda可以更加方

2019-08-19