Почему метод без входного параметра можно использовать для замены функции - PullRequest
3 голосов
/ 06 марта 2020

Для следующего фрагмента кода в calculateOnShipments один параметр принимает функцию с Shipment в качестве ввода и Double в качестве вывода.

Function<Shipment, Double> f

1) Почему ее можно вызвать с помощью Shipment::calculateWeight? calculateWeight() не принимает никаких параметров, хотя возвращает Double

public double calculateWeight()

2) Я пытаюсь закомментировать calculateWeight(), но оставлю calculateWeight(Shipment s1), затем появляется сообщение об ошибке

"Невозможно сделать статическую c ссылку на нестатический c метод CalculateWeight (Отгрузка) из типа Отгрузка"

Что означает это сообщение? почему он сказал, что ссылка c? прежде чем я прокомментирую 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 ]

2 голосов
/ 06 марта 2020

почему его можно назвать Shipment::calculateWeight? calculateWeight() не принимает никаких параметров, хотя возвращает double

Его можно вызвать с помощью ссылки на метод, поскольку ссылка на метод представляет код для вызова метода calculateWeight для shipment, который принимается в качестве входных данных для Function<Shipment, Double>. Прочитайте их для дальнейшей взаимосвязи -

shipment -> shipment.calculateWeight()

или далее

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

Я пытаюсь закомментироватьrateWeight (), но оставлю в расчетеWight (Отгрузка) s1), возникает ошибка msg

Теперь, если вы поняли вышеприведенное лямбда-представление, ссылка на метод невозможна без того, чтобы для вызывающего метода 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).

1 голос
/ 06 марта 2020

1) По какой причине он может быть вызван отгрузкой :: CalculateWeight? Функция расчета в весе () не принимает никаких параметров, […]

calculateWeight() - это не статический c метод для класса Shipment, поэтому в некотором смысле он принимает неявный this параметр типа Shipment. Так что Shipment::calculateWeight - это функция, которая принимает этот единственный параметр. (Если бы calculateWeight() был нестатическим c методом или если вы написали shipment1::calculateWeight вместо Shipment::calculateWeight, чтобы экземпляр запекся в ссылку на метод, то это была бы функция без параметров.)


2) Я пытаюсь закомментироватьrateWeight (), но оставляю CalculateWeight (Shipment s1), тогда возникает ошибка msg

"Невозможно сделать stati c ссылка на не-stati c метод CalculateWeight (Отправка) из типа Отправка "

Что означает это сообщение? почему он сказал, что ссылка c? […]

Это хороший вопрос. Основная проблема заключается в том, что в отношении ссылок на методы calculateWeight(Shipment s1) принимает два параметра: неявный this параметр типа Shipment (поскольку это метод экземпляра в классе Shipment) и явный параметр s1 типа Shipment.

Сообщение об ошибке выглядит странно; по сути, компилятор говорит: «это не метод stati c, поэтому вам нужно дать ему экземпляр», идея в том, что вы могли бы написать shipment1::calculateWeight вместо Shipment::calculateWeight, чтобы указать экземпляр, которым он должен быть звонил.

...