通过方法引用实现Comparator:为何compareOrder参数不匹配仍可正常工作?
问题:方法引用匹配函数式接口的疑问
泛型类Yxj代码
public class Yxj<T> { private T[] data; private int size = 0; private final Comparator<? super T> comparator; public Yxj(Comparator<? super T> c) { data= (T[]) new Object[16]; comparator = c; } public void addItem(T t){ data[size++] = t; } public int sort(){ return comparator.compare(data[0], data[1]); } public T[] getData(){ return data; } }
Norwich类代码
public class Norwich { private int order; public Norwich(int o) { order = o; } public int getOrder() { return order; } public void setOrder(int order) { this.order = order; } public int compareOrder(Norwich n) { if (order > n.getOrder()) { return 2; } else if (order == n.getOrder()) { return 0; } else { return -3; } } }
主方法代码
Yxj<Norwich> norwichYxj = new Yxj<>(Norwich::compareOrder); norwichYxj.addItem(new Norwich(9)); norwichYxj.addItem(new Norwich(1)); System.out.println(norwichYxj.sort());
用户疑问
为何compareOrder方法的参数列表与Comparator接口的compare方法不一致,却仍能通过方法引用正确实现该函数式接口并正常工作?
解答
这是因为Java方法引用的特殊匹配规则——当你用Norwich::compareOrder这种实例方法引用匹配Comparator<Norwich>的compare(T o1, T o2)方法时,Java会自动把函数式接口的第一个参数作为调用实例方法的对象,第二个参数作为实例方法的入参。
具体来说:
Comparator<Norwich>的compare方法需要两个Norwich类型参数,返回intNorwich的compareOrder是实例方法,原本需要一个Norwich参数,完整调用形式是o1.compareOrder(o2)
Java的方法引用机制会自动完成绑定,相当于生成了这样的匿名实现:
new Comparator<Norwich>() { @Override public int compare(Norwich o1, Norwich o2) { return o1.compareOrder(o2); } }
另外补充一点:你返回的2、0、-3虽然不是Comparator约定的标准1、0、-1,但接口只要求返回值的正负性(正数表示前者大于后者,负数表示前者小于后者,0表示相等),所以代码能正常运行。
内容的提问来源于stack exchange,提问作者Zhiqiang Guo
相关产品推荐
相关产品推荐

