有 Java 编程相关的问题?

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

java为什么没有输入参数的方法可以用来替换函数<T,R>

对于以下代码段,在calculateOnShipments中,一个参数接受一个函数,其中Shipment作为输入Double作为输出

Function<Shipment, Double> f

1)为什么可以使用Shipment::calculateWeight调用它calculateWeight()不接受任何参数,尽管它返回Double

public double calculateWeight()

2)我试图注释掉calculateWeight(),但保留calculateWeight(Shipment s1),然后出现错误消息

"Cannot make a static reference to the non-static method calculateWeight(Shipment) from the type Shipment"

这是什么意思?为什么说是静态引用?在我评论calculateWeight()之前,为什么没有错误消息

class Shipment {
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        List<Shipment> l = new ArrayList<Shipment>();
        l.add(new Shipment());
        l.add(new Shipment());
        Shipment shipment1 = new Shipment();
        // Using an anonymous class
        List<Double> lw = shipment1.calculateOnShipments(l, Shipment::calculateWeight);
        System.out.println(lw);//[0.0,0.0]
    }

    public double calculateWeight() {
        double weight = 0;
        // Calculate weight
        return weight;
    }

    public double calculateWeight(Shipment s1) {
        double weight = 1;
        // Calculate weight
        return weight;
    }

    public List<Double> calculateOnShipments(
            List<Shipment> l, Function<Shipment, Double> f) {
        List<Double> results = new ArrayList<>();
        for (Shipment s : l) {
            results.add(f.apply(s));
        }
        return results;
    }
}

共 (2) 个答案

  1. # 1 楼答案

    why it can be called by Shipment::calculateWeight? calculateWeight() does not accept any parameter, although it return double

    可以使用方法引用调用它,因为方法引用表示调用shipment上的方法calculateWeight的代码,该方法被接受为Function<Shipment, Double>的输入。阅读以下内容,了解更多相关信息

    shipment -> shipment.calculateWeight()
    

    或者更进一步

    new Function<Shipment, Double>() {
        @Override
        public Double apply(Shipment shipment) {
            return shipment.calculateWeight();
        }
    })
    

    I try to comment out the calculateWeight() but keep the calculateWeight(Shipment s1), then there is a error msg

    现在,如果您已经理解了上面的lambda表示,那么如果没有calculateWeight方法调用,方法引用是不可能的,因为调用calculateWeight方法需要一个装运,一个是实例,在该实例上调用该方法,另一个是传递给该方法作为参数。那可能是

    shipment -> shipment.calculateWeight(shipment1)
    

    请注意,将方法转换为static,例如

    public static double calculateWeight(Shipment s1)
    

    将导致推断方法引用以接受实例作为参数本身,并将作为:

    List<Double> lw = shipment1.calculateOnShipments(l, Shipment::calculateWeight)
    

    其中Shipment::calculateWeight表示shipment -> calculateWeight(shipment)

  2. # 2 楼答案

    1) By why it can be called by Shipment::calculateWeight? calculateWeight() does not accept any parameter, […]

    calculateWeight()是类Shipment上的一个非静态方法,因此在某种意义上,它采用类型为Shipment的隐式this参数。所以Shipment::calculateWeight是一个接受这个参数的函数。(如果calculateWeight()是一个非静态方法,或者如果您编写了shipment1::calculateWeight而不是Shipment::calculateWeight以便将实例烘焙到方法引用中,那么这将是一个没有参数的函数。)


    2) I try to comment out the calculateWeight() but keep the calculateWeight(Shipment s1), then there is a error msg

    "Cannot make a static reference to the non-static method calculateWeight(Shipment) from the type Shipment"

    这是什么意思?为什么说是静态引用?[…]

    这是个好问题。潜在的问题是,就方法引用而言,calculateWeight(Shipment s1)需要两个参数:类型Shipment的隐式this参数(因为它是类Shipment上的实例方法),以及类型Shipment的显式s1参数

    错误信息会很奇怪;本质上,编译器是在说“这不是一个静态方法,所以你需要给它一个实例”,意思是你可以写shipment1::calculateWeight而不是Shipment::calculateWeight来指定应该调用它的实例