Java 8 方法引用可替代仅调用一个已有方法的 Lambda 表达式,使 HashMap 遍历更简洁;方法引用不执行逻辑,而是将操作委托给已有方法,如 forEach(BiConsumer) 配合方法引用。

Java 8 引入方法引用后,可以用它替代 Lambda 表达式中“仅调用一个已有方法”的场景,让 HashMap 遍历时的代码更简洁。关键在于:方法引用本身不执行逻辑,而是把“对每个键值对要做的操作”交给已存在的方法来处理。
用 forEach + 方法引用遍历键值对
HashMap 的 forEach(BiConsumer super K, ? super V> action) 接收一个接受两个参数(key 和 value)的函数式接口。只要有一个静态方法或实例方法签名匹配 (K, V) -> void,就能用方法引用代替 Lambda。
- 静态方法引用:
MyUtils::printEntry(要求该方法是public static void printEntry(String key, Integer value)) - 实例方法引用(绑定对象):
printer::accept(要求printer是实现了BiConsumer<string integer></string>的对象) - 注意:不能直接用
System.out::println,因为println是重载方法,编译器无法推断接收两个参数的版本
先提取成独立方法再引用,提升可读性
比起写内联 Lambda,把遍历逻辑抽成有语义的方法,再用方法引用,既清晰又利于复用:
例如:public class LogHelper {
public static void logUser(String username, Integer loginCount) {
System.out.printf("用户 %s 登录 %d 次%n", username, loginCount);
}
}
// 使用时
map.forEach(LogHelper::logUser);
这样比 map.forEach((k, v) -> System.out.printf("用户 %s 登录 %d 次%n", k, v)); 更易懂、易测试、易修改。
立即学习“Java免费学习笔记(深入)”;
配合 Stream API 时也能用方法引用
如果需要过滤或转换后再遍历,可用 entrySet().stream(),其中 forEach 同样支持方法引用 —— 只不过此时方法签名需为 Map.Entry<k> -> void</k>:
- 静态方法:
EntryLogger::handleEntry(参数类型为Map.Entry<string integer></string>) - 实例方法:
logger::log(前提是logger.log(Map.Entry)存在) - 常见简写:
System.out::println可直接用于entrySet().stream().forEach(System.out::println),因为println(Object)匹配Entry类型
不适用方法引用的典型情况
以下情形不适合硬套方法引用,强行使用反而降低可读性:
- 逻辑包含条件判断、多行语句或局部变量计算(如
if (v > 10) sendAlert(k)) - 需要捕获异常但未声明 throws(方法引用无法添加 try-catch)
- 目标方法参数类型与 key/value 不严格匹配(比如方法参数是
Object而不是具体泛型类型),可能触发编译错误或运行时 ClassCastException


















