朋友问我Java中“::”是什么意思?我汗流浃背了......

简介: 朋友问我Java中“::”是什么意思?我汗流浃背了......

一:什么是::?

JDK1.8中引入了Lambda表达式,因此也在JDK1.8引入了::。双冒号 :: 是方法引用(Method Reference)的一种语法。方法引用是一种更简洁和更易读的方式来表示一个函数式接口的实现,它可以看作是lambda表达式的简写。

二:方法引用的几种类型

1.引用静态方法

import java.util.function.Function;
 
/**
 * @author: dlwlrma
 * @data 2024年06月30日 20:00
 * @Description: TODO: 测试静态方法引用
 */
public class TestStaticMethod {
    public static void main(String[] args) {
        Function<String, Integer> function = Integer::parseInt;
        Integer apply = function.apply("18");
        System.out.println("apply = " + apply);//apply = 18
    }
}

以上代码等同于以下代码:

/**
 * @author: dlwlrma
 * @data 2024年06月30日 20:00
 * @Description: TODO: 测试静态方法引用
 */
public class TestStaticMethod {
    public static void main(String[] args) {
        
        Function<String, Integer> parseInt = s -> Integer.parseInt(s);
        Integer apply1 = parseInt.apply("18");
        System.out.println("apply1 = " + apply1);
    }
}

底层源码如下:

2.引用特定对象的实例方法

import java.util.function.Supplier;
 
/**
 * @author: dlwlrma
 * @data 2024年06月30日 20:25
 * @Description: TODO: 测试使用实例对象和方法名引用该对象的实例方法。
 */
public class TestIntanceMethod {
    public static void main(String[] args) {
        String str = "你好";
        Supplier<Integer> runnable = str::length;
        Integer i = runnable.get();
        System.out.println("i = " + i);//i=2;
    }
}

以上代码等同于以下代码 :

import java.util.function.Supplier;
 
/**
 * @author: dlwlrma
 * @data 2024年06月30日 20:25
 * @Description: TODO: 测试使用实例对象和方法名引用该对象的实例方法。
 */
public class TestIntanceMethod {
    public static void main(String[] args) {
        String str = "你好";
        Supplier<Integer> runnable1 = () -> str.length();
        Integer i = runnable1.get();
        System.out.println("i = " + i);
 
//        Supplier<Integer> runnable1 = () -> str.length();
    }
}

3.引用特定类型的任意对象的实例方法

import java.util.function.Function;
 
/**
 * @author: dlwlrma
 * @data 2024年06月30日 20:35
 * @Description: TODO: 使用类名和方法名引用该类的实例方法,适用于任意对象。
 */
public class TestIntanceMethod2 {
    public static void main(String[] args) {
        Function<String, Integer> str = String::length;
        Integer length = str.apply("Hello Java");
        System.out.println(length);//10
    }
}

以上代码等同于以下代码

import java.util.function.Function;
 
/**
 * @author: dlwlrma
 * @data 2024年06月30日 20:35
 * @Description: TODO: 使用类名和方法名引用该类的实例方法,适用于任意对象。
 */
public class TestIntanceMethod2 {
    public static void main(String[] args) {
 
        Function<String, Integer> str1 = s -> s.length();
        Integer length = str1.apply("Hello Java");
        System.out.println(length);//10
    }
}

4.引用构造方法

import java.util.function.Supplier;
 
/**
 * @author: dlwlrma
 * @data 2024年06月30日 20:40
 * @Description: TODO:使用类名和 new 关键字引用构造方法。
 */
public class TestConstructorMethod {
    public static void main(String[] args) {
        Supplier<StringBuilder> stringBuilderSupplier = StringBuilder::new;
        StringBuilder stringBuilder = stringBuilderSupplier.get();
        System.out.println(stringBuilder); // 输出空的 StringBuilder 对象
    }
}

以上代码等同于以下代码

import java.util.function.Supplier;
 
/**
 * @author: dlwlrma
 * @data 2024年06月30日 20:40
 * @Description: TODO:使用类名和 new 关键字引用构造方法。
 */
public class TestConstructorMethod {
    public static void main(String[] args) {
       
        Supplier<StringBuilder> stringBuilderSupplier1 = () -> new StringBuilder();
        StringBuilder stringBuilder1 = stringBuilderSupplier.get();
        System.out.println(stringBuilder); 
    }
}

三:方法引用的适用场景

方法引用可以用来简化lambda表达式,使代码更简洁易读。它在需要实现函数式接口时特别有用,例如在使用java.util.function包中的接口时。

import java.util.Arrays;
import java.util.List;
 
/**
 * @author: dlwlrma
 * @data 2024年06月30日 20:44
 * @Description: TODO: 方法引用的实现场景
 */
public class TestDemo {
    public static void main(String[] args) {
        List<String> names = Arrays.asList("张三", "李四", "王五");
 
        // 使用 lambda 表达式
        names.forEach(name -> System.out.println(name));
 
        // 使用方法引用
        names.forEach(System.out::println);
    }
}

在这个示例中,System.out::println是对System.out对象的println方法的引用,它替代了name -> System.out.println(name)的lambda表达式,使代码更加简洁。

四:总结

在Java中,双冒号(::)可以用作方法引用和构造函数引用的符号。它的好处包括:

1. 简化代码:使用双冒号可以将一些重复的代码进行简化。通过引用已存在的方法或构造函数,可以避免重复编写相同的代码逻辑。

2. 代码可读性更高:通过使用双冒号,可以更清晰地表示代码的意图。它能够更直观地表达方法引用或构造函数引用的含义,使代码更易于理解和维护。

3. 提高代码的可复用性:通过方法引用或构造函数引用,可以将方法或构造函数作为参数传递给其他方法,使代码更加灵活和可复用。

4. 支持函数式编程风格:双冒号操作符在使用Lambda表达式时非常有用。它可以帮助我们将方法引用或构造函数引用与函数式接口一起使用,从而实现函数式编程的目标。

总结来说,双冒号操作符在Java中有助于简化代码、提高可读性、提高代码的可复用性,以及支持函数式编程风格。

相关文章
|
11月前
|
人工智能 编解码 芯片
告别低效沟通|让技术提问不再头疼-这套高效AI提问模板来帮你
不会向ai提问,不知道怎么提问的 可以看看
21239 1
告别低效沟通|让技术提问不再头疼-这套高效AI提问模板来帮你
|
Java Spring
Spring中的ID生成器
Spring中的ID生成器
652 0
|
10月前
|
API 开发工具 开发者
HarmonyOS NEXT实战:拨打电话
本课程介绍如何在HarmonyOS SDK中使用Telephony Kit实现拨打电话功能。通过CallPhoneDemoPage示例,讲解如何输入电话号码并调用makeCall接口拨号,涉及call模块的使用及设备通话能力检测。
8073 0
|
7月前
|
SQL Java 数据库连接
区分iBatis与MyBatis:两个Java数据库框架的比较
总结起来:虽然从技术角度看,iBATIS已经停止更新但仍然可用;然而考虑到长期项目健康度及未来可能需求变化情况下MYBATISS无疑会是一个更佳选择因其具备良好生命周期管理机制同时也因为社区力量背书确保问题修复新特征添加速度快捷有效.
642 12
|
弹性计算 Linux Windows
如何升级计算巢服务实例版本,从而支持更便捷、可视化的游戏配置
现在你可以参考这篇教程,将之前老版本的幻兽帕鲁计算巢服务,升级到最新版本,支持最新版本的管理配置界面。包括修改游戏配置、重启游戏、存档管理等功能。
如何升级计算巢服务实例版本,从而支持更便捷、可视化的游戏配置
|
存储 传感器 数据采集
大数据
大数据是指数据量庞大(Volume)、增长迅速(Velocity)、类型多样(Variety)、价值密度低(Value)但潜力巨大的数据集。其来源包括互联网、物联网及企业内部数据。处理技术涵盖采集、预处理、存储、分析与可视化。应用领域涉及商业智能、金融、医疗、交通及公共服务等,助力决策优化与创新。
1105 8
|
缓存 监控 Java
深入解析Nacos配置中心的动态配置更新技术
深入解析Nacos配置中心的动态配置更新技术