有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java比较器比较类型推断

让我们假设更改Comparator.comparing源代码

public static <T, U extends Comparable<? super U>> Comparator<T> comparing(
    Function<? super T, ? extends U> keyExtractor)
{
  Objects.requireNonNull(keyExtractor);
  return (Comparator<T> & Serializable) (c1, c2) -> keyExtractor.apply(c1).compareTo(keyExtractor.apply(c2));
}

public static <T, U extends Comparable<? super U>> Comparator<T> comparing(
    Function<T, U> keyExtractor)
{
  Objects.requireNonNull(keyExtractor);
  return (Comparator<T> & Serializable) (c1, c2) -> keyExtractor.apply(c1).compareTo(keyExtractor.apply(c2));
}

我们有以下课程

class PhysicalObject {
  double weight;
  public Double getWeight(){
    return weight;  
  }
}
class Car extends PhysicalObject {}

以下statement未编译

Function<PhysicalObject, Double> weight = p->p.getWeight();

Comparator<Car> c = HypotheticComparators.comparing(weight);

而这个编译Comparator<Car> c3_1 = HypotheticComparators.comparing(PhysicalObject::getWeight);

我知道第一条语句无法编译是因为修改后的比较函数没有有界通配符(? super T),但是为什么第二条语句可以编译而没有任何问题呢


共 (1) 个答案

  1. # 1 楼答案

    comparing定义为:

    Comparator<T> comparing(Function<T, U> keyExtractor) // abbreviated
    

    声明:

    Comparator<Car> c = comparing(weight);
    

    要求参数是Function<Car, ?>,但weightFunction<PhysicalObject, Double>,因此会出现编译错误

    然而,当

    Comparator<Car> c3_1 = comparing(PhysicalObject::getWeight);
    

    超类PhysicalObjectDouble getWeight()充分实现了Function<Car, ?>方法? apply(Car t),因为t->getWeight()是对该方法的调用

    PhysicalObject::getWeight方法引用类似于以下lambda:

    Comparator<Car> c3_1 = comparing((Car t) -> {
        PhysicalObject p = t;
        return p.getWeight(); // call PhysicalObject::getWeight
    });
    

    或以下匿名类:

    Comparator<Car> c3_1 = comparing(new Function<Car, Double>() {
        @Override
        public Double apply(Car t) {
            PhysicalObject p = t;
            return p.getWeight();
        }
    });
    

    方法引用中允许从CarPhysicalObject的加宽转换