当前位置: 首页 > news >正文

【Java】Java 中函数作为参数传递详解

请添加图片描述


文章目录

    • 一、前言
    • 二、为什么要把函数作为参数传递?
    • 三、实现函数传参的关键:函数式接口
      • 函数式接口定义
    • 四、JDK 内置的函数式接口
      • Consumer 示例
      • Function 示例
      • Predicate 示例
      • Supplier 示例
    • 五、结合方法引用(`::`)的写法
    • 六、Stream API 中的函数传参
    • 七、总结
    • 八、参考资料


一、前言

在传统的 Java 开发中,我们习惯将数据作为参数传递给方法。
但从 Java 8 开始,Java 引入了 Lambda 表达式方法引用
让我们能够像在函数式语言中那样,把“函数(行为)”本身作为参数进行传递。

这种特性让 Java 更加灵活、简洁,也极大地推动了 函数式编程(Functional Programming) 在 Java 中的应用。


二、为什么要把函数作为参数传递?

在面向对象编程中,我们常常写这样的代码:

public void process(String input) {System.out.println(input.toUpperCase());
}

如果你想对 input 做不同的处理逻辑,比如转小写、反转、加前缀……
通常要写多个方法,或者在方法内部用 if/else

但如果我们能将“处理逻辑”作为函数传入,就可以让方法更通用:

public void process(String input, Function<String, String> operation) {System.out.println(operation.apply(input));
}

于是我们就能这样灵活调用:

process("Java", s -> s.toUpperCase());    // 转大写
process("Java", s -> s.toLowerCase());    // 转小写
process("Java", s -> "Hello " + s);       // 加前缀

是不是非常优雅?这就是“函数作为参数传递”的威力。


三、实现函数传参的关键:函数式接口

在 Java 中,函数不是一等公民,不能直接像 Python 那样传递函数。
但 Java 通过 函数式接口(Functional Interface) 实现了类似功能。

函数式接口定义

函数式接口就是只包含一个抽象方法的接口。

例如:

@FunctionalInterface
interface MyOperation {void execute();
}

然后我们就可以传入一个 Lambda 表达式:

public class Demo {public static void main(String[] args) {doSomething(() -> System.out.println("Hello Lambda!"));}public static void doSomething(MyOperation op) {op.execute();  // 调用传入的函数}
}

输出:

Hello Lambda!

四、JDK 内置的函数式接口

Java 在 java.util.function 包中已经内置了大量常用函数式接口。

接口名方法签名功能说明
Consumer<T>void accept(T t)接收一个参数,无返回值
Supplier<T>T get()无参数,有返回值
Function<T, R>R apply(T t)接收参数并返回结果
Predicate<T>boolean test(T t)接收参数并返回布尔值

Consumer 示例

import java.util.function.Consumer;public class ConsumerDemo {public static void main(String[] args) {processData("Java", s -> System.out.println("Hello, " + s + "!"));}public static void processData(String data, Consumer<String> action) {action.accept(data);}
}

输出:

Hello, Java!

Function 示例

import java.util.function.Function;public class FunctionDemo {public static void main(String[] args) {transform("Lambda", s -> s.toUpperCase());transform("World", s -> "Hello " + s);}public static void transform(String data, Function<String, String> func) {String result = func.apply(data);System.out.println(result);}
}

输出:

LAMBDA
Hello World

Predicate 示例

import java.util.function.Predicate;public class PredicateDemo {public static void main(String[] args) {check("OpenAI", s -> s.length() > 5);check("GPT", s -> s.startsWith("G"));}public static void check(String data, Predicate<String> condition) {System.out.println(condition.test(data));}
}

输出:

true
true

Supplier 示例

import java.util.function.Supplier;public class SupplierDemo {public static void main(String[] args) {printValue(() -> "Hello from Supplier!");}public static void printValue(Supplier<String> supplier) {System.out.println(supplier.get());}
}

输出:

Hello from Supplier!

五、结合方法引用(::)的写法

当传入的 Lambda 只是调用某个已有方法时,可以用 方法引用 简化:

import java.util.List;public class MethodRefDemo {public void print(String s) {System.out.println("Item: " + s);}public void printAll(List<String> list) {// 等价于 list.forEach(s -> this.print(s));list.forEach(this::print);}public static void main(String[] args) {new MethodRefDemo().printAll(List.of("Java", "Python", "C++"));}
}

输出:

Item: Java
Item: Python
Item: C++

六、Stream API 中的函数传参

函数式接口的最大用途之一,就是在 Stream API 中传递行为逻辑。

import java.util.List;public class StreamExample {public static void main(String[] args) {List<String> names = List.of("Alice", "Bob", "Charlie", "David");names.stream().filter(name -> name.length() > 3)     // 传入 Predicate.map(String::toUpperCase)              // 传入 Function.forEach(System.out::println);         // 传入 Consumer}
}

输出:

ALICE
CHARLIE
DAVID

这就是 Java 函数式编程的典型应用场景。


七、总结

概念说明
函数式接口只包含一个抽象方法的接口,用于支持 Lambda 表达式
Lambda 表达式让你能像传递数据一样传递行为
方法引用 (::)Lambda 的简写方式,可直接引用已有方法
常用接口ConsumerSupplierFunctionPredicate
典型应用Stream API、回调函数、异步任务等

八、参考资料

Java-函数作为参数的传递与使用_java 函数参数-CSDN博客

Python中将函数作为参数传递给函数

http://www.dtcms.com/a/577222.html

相关文章:

  • 企业网站备案费用英文案例网站
  • 乐迪信息:采煤机状态如何?AI摄像机远程智能识别,故障早发现
  • 4.2.3 指令的寻址方式【2010统考真题】
  • 大三程序猿的刷题日常 Day 5
  • Java基础复习-下-多线程-网络编程-反射
  • 便携软件注册器:让便携版的软件秒变默认程序
  • 知识体系(四)Agent
  • 48 进 48 出纯音频矩阵:大型场景音频调度的技术革新与应用实践
  • 男女做暖暖的试看网站漫画网站图片一般多大
  • 萤石开放平台机器人音视频对接流程
  • 站长之家特效网站wordpress 端口号
  • 网页设计与网站建设教材北京企业网站优化
  • 深圳品牌网站设计公司价格深圳非凡网站建设公司
  • 5.基础--SQL--DDL数据库操作
  • 小马智行港股上市:自动驾驶从“技术追跑”到“商业领跑”的里程碑
  • 【stm32协议外设篇】- SU03T 智能语音模块
  • 修改PostgreSQL测试脚本使之在cedardb中运行并分析日志
  • “融资热潮”来临!商用车自动驾驶拐点已至?
  • 告别资源瓶颈与漫长周期:覆盖自动驾驶全研发周期的SiL验证方案
  • SQL50+Hot100系列(11.6)
  • 【Ubuntu】Ubuntu 服务器升级系统操作记录
  • 模具厂咋做网站阿里巴巴网站分类板块做全屏
  • openvela 时钟框架概述
  • 中国室内设计师资格证小企业如何优化网站建设
  • 排序算法稳定性判断
  • 全面详解常见网络协议默认端口号及其应用场景
  • 详解 零拷贝(Zero Copy):mmap、sendfile、DMA gather、splice
  • 学Java第四十二天--------Arrays工具类和Lambda表达式
  • PDF-XChange Editor丨加拿大PDF编辑转换工具
  • 家里的飞牛NAS连接的明明是千兆宽带,异地访问时网速都不对?