Java方法引用作为Lambda入参的处理及Map获取返回null原因
为什么方法引用
iF::apply存入Map后调用get返回null? 问题场景:
将方法引用iF::apply存入Context类的HashMap集合后,使用看似相同的iF::apply调用get方法,结果返回null。
代码示例:
public void test() { Context context = new Context(); IF iF = new IF(); context.put(iF::apply, 100); Integer v = context.get(iF::apply); System.out.println(v); } class IF implements Function<String, Integer> { @Override public Integer apply(String s) { return 200; } } class Context { private Map<Function, Object> items = new HashMap<>(); public <T, R> void put(Function<T, R> name, R value) { items.put(name, value); } public <T, R> R get(Function<T, R> name) { return (R)items.get(name); } }
核心原因
Java中,每次使用对象::方法这种形式的方法引用时,都会生成一个全新的函数式接口实例。哪怕是同一个对象的同一个方法,两次写iF::apply得到的都是不同的Function对象。
而HashMap判断键是否相等的逻辑是:先比较哈希值,再调用equals方法。这两个不同的Function实例哈希值不同,equals也返回false,所以第二次get的时候找不到对应的键,返回null。
你可以简单验证这一点:
Function<String, Integer> f1 = iF::apply; Function<String, Integer> f2 = iF::apply; System.out.println(f1 == f2); // 输出false,证明是两个不同对象
解决方法
把方法引用提前赋值给一个变量,后续存和取都用这个变量:
public void test() { Context context = new Context(); IF iF = new IF(); // 提前把方法引用赋值给变量 Function<String, Integer> targetFunc = iF::apply; context.put(targetFunc, 100); Integer v = context.get(targetFunc); System.out.println(v); // 此时输出100 }
内容的提问来源于stack exchange,提问作者Jack Ma
相关产品推荐
相关产品推荐

