1 方法引用:代码范例
Java 8 中新增加了 方法引用 这个概念。但,什么是方法引用呢 ?
我们先来看一个例子,下面这个范例演示了如何遍历字符串列表并进行一些操作
package com.sjh.test.java8;
import java.util.Arrays;
import java.util.List;
public class LambdaTest1 {
public static void main(String[] args)
{
LambdaTest1 tester = new LambdaTest1();
tester.run();
}
public void run()
{
List<String> list = Arrays.asList("Action","Cebci","Back");
// 输出
for(String st: list){
System.out.println(st);
}
// 转换为大写
for(String st: list){
upperAndPrint(st);
}
}
public static void upperAndPrint(String s)
{
System.out.println(s.toUpperCase());
}
}
执行结果:
/Library/Java/JavaVirtualMachines/jdk1.8.0_171.jdk/...com.sjh.test.java8.LambdaTest1
Action
Cebci
Back
ACTION
CEBCI
BACK
Process finished with exit code 0
看到那重复的 for(String st: list)
我们可以使用 Java 8 新增的 lambda 表达式和 forEach
改造下让把代码变的更简洁一些。
package com.sjh.test.java8;
import java.util.Arrays;
import java.util.List;
public class LambdaTest2 {
public static void main(String[] args)
{
LambdaTest2 tester = new LambdaTest2();
tester.run();
}
public void run()
{
List<String> list = Arrays.asList("Action","Cebci","Back");
// 输出
list.forEach(item -> System.out.println(item));
// 转换为大写
list.forEach(item -> upperAndPrint(item));
}
public static void upperAndPrint(String s)
{
System.out.println(s.toUpperCase());
}
}
运行结果:
/Library/Java/JavaVirtualMachines/jdk1.8.0_171.jdk/... com.sjh.test.java8.LambdaTest2
Action
Cebci
Back
ACTION
CEBCI
BACK
Process finished with exit code 0
果然、使用 Lambda 表达式真的是简洁了不少,但是,还有没有更简单的方式?
比如 item -> System.out.println(item)
这个表达式,其实就是调用 System.out.println()
方法,并把 forEach
迭代列表生成的唯一参数 item
传给它而已
比如 item -> upperAndPrint(item)
这个表达式,也是一样啊,就是把 forEach
生成的唯一参数 item
传给给 upperAndPrint()
方法而已。
那么我们可不可以直接传递方法名给 forEach
呢?
试试下面这样方法吧!
package com.sjh.test.java8;
import java.util.Arrays;
import java.util.List;
public class LambdaTest3 {
public static void main(String[] args)
{
LambdaTest3 tester = new LambdaTest3();
tester.run();
}
public void run()
{
List<String> list = Arrays.asList("Action","Cebci","Back");
// 输出
list.forEach(System.out.println);
// 转换为大写
list.forEach(upperAndPrint);
}
public static void upperAndPrint(String s)
{
System.out.println(s.toUpperCase());
}
}
哎呀,好像遇到了点问题:
Information:java: Errors occurred while compiling module 'test'
Information:javac 1.8.0_171 was used to compile java sources
Information:2020-05-29 16:30 - Build completed with 2 errors and 0 warnings in 2 s 35 ms
/Users/sunjiahao/Develop/gitee_project/test/src/com/sjh/test/java8/LambdaTest3.java
Error:(19, 32) java: 找不到符号
符号: 变量 println
位置: 类型为java.io.PrintStream的变量 out
Error:(22, 22) java: 找不到符号
符号: 变量 upperAndPrint
位置: 类 com.sjh.test.java8.LambdaTest3
这在所有的 Java 版本中都会报错,但是自 Java 8 开始,还真是可以直接传递方法名的,只是我们使用的方式不对而已。
那么我们来调整一下,再看看。
package com.sjh.test.java8;
import java.util.Arrays;
import java.util.List;
public class LambdaTest3 {
public static void main(String[] args)
{
LambdaTest3 tester = new LambdaTest3();
tester.run();
}
public void run()
{
List<String> list = Arrays.asList("Action","Cebci","Back");
// 输出
list.forEach(System.out::println);
// 转换为大写
list.forEach(LambdaTest3::upperAndPrint);
}
public static void upperAndPrint(String s)
{
System.out.println(s.toUpperCase());
}
}
运行结果:
/Library/Java/JavaVirtualMachines/jdk1.8.0_171.jdk/...com.sjh.test.java8.LambdaTest3
Action
Cebci
Back
ACTION
CEBCI
BACK
Process finished with exit code 0
OK,现在正确了。
在这个正确的方法中,有两个重点:
1、 方法名和类名之间不是使用点号 ( .
) 而是使用两个冒号 ::
。
2、 提供的方法名必须包含类名,如果没有引入该类名,则需要使用全限定类名,也就是需要添加包名作为前缀。
这种使用方法名做参数的做法,在 Java 8 中称之为 「 方法引用 」
2 方法引用:总结
方法引用 是 Java 8 新增加的功能。方法引用有点类似于 C / C++ 中的 函数指针 ,通过方法名称指向方法。
Java 8 中的方法引用通过 ::
符号引用方法,而且支持一下类型的方法引用
1、 静态方法
2、 实例方法
3、 使用 new
运算符的构造函数。例如 TreeSet::new
重写上面的范例,演示下如何引用静态方法和实例方法
package com.sjh.test.java8;
import java.util.Arrays;
import java.util.List;
public class LambdaTest4 {
public static void main(String[] args)
{
LambdaTest4 tester = new LambdaTest4();
tester.run();
}
public void run()
{
List<String> list = Arrays.asList("Action","Cebci","Back");
// 输出
list.forEach(System.out::println);
// 转换为大写
list.forEach(LambdaTest4::upperAndPrint);
// 转换为小写并输出
list.forEach(this::lowerAndPrint);
}
public void lowerAndPrint(String s)
{
System.out.println(s.toLowerCase());
}
public static void upperAndPrint(String s)
{
System.out.println(s.toUpperCase());
}
}
运行结果:
/Library/Java/JavaVirtualMachines/jdk1.8.0_171.jdk/...com.sjh.test.java8.LambdaTest4
Action
Cebci
Back
ACTION
CEBCI
BACK
action
cebci
back
Process finished with exit code 0
end