前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Java 8 新特性|方法引用

Java 8 新特性|方法引用

作者头像
Java小技巧
发布2022-05-23 12:49:31
2980
发布2022-05-23 12:49:31
举报
文章被收录于专栏:Java小技巧

1 方法引用:代码范例

Java 8 中新增加了 方法引用 这个概念。但,什么是方法引用呢 ?

我们先来看一个例子,下面这个范例演示了如何遍历字符串列表并进行一些操作

代码语言:javascript
复制
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());
    }
}

执行结果:

代码语言:javascript
复制
/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 改造下让把代码变的更简洁一些。

代码语言:javascript
复制
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());
    }
}

运行结果:

代码语言:javascript
复制
/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 呢?

试试下面这样方法吧!

代码语言:javascript
复制
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());
    }
}

哎呀,好像遇到了点问题:

代码语言:javascript
复制
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 开始,还真是可以直接传递方法名的,只是我们使用的方式不对而已。

那么我们来调整一下,再看看。

代码语言:javascript
复制
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());
    }
}

运行结果:

代码语言:javascript
复制
/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

重写上面的范例,演示下如何引用静态方法和实例方法

代码语言:javascript
复制
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());
    }

}

运行结果:

代码语言:javascript
复制
/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

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-05-29,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Java小技巧 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档