如何将 class 字段放入方法参数中以避免代码重复

How to put class field into method argument to avoid code repeat

我目前正在解决这个问题。例如。我有两个 classes。一个用于项目,第二个用于这些项目的某种记录。如果我想使用几种方法从集合中的所有项目中获取不同种类的平均值,我需要做什么。在我的例子中,有价格、质量和体积的平均值。这些方法是重复的,唯一不同的是 getter。那么,是否有任何选项,如何使用一个私有方法进行计数,另外三个 public,将使用这个私有方法并以某种方式将字段作为参数?

项目class

public class Item {
    private double price;
    private double mass;
    private double volume;

    public double getPrice() {
        return price;
    }

    public double getMass() {
        return mass;
    }

    public double getVolume() {
        return volume;
    }
}

库存class

package model;

import java.util.ArrayList;
import java.util.List;

public class Stock {
    private List<Item> items;

    public Stock() {
        items = new ArrayList<>();
    }

    public double getAveragePrice() {
        double sum = 0;

        if (!items.isEmpty()) {
            for (Item item : items) {
                sum += item.getPrice();
            }
            return sum / items.size();
        }
        return sum;
    }

    public double getAverageMass() {
        double sum = 0;

        if (!items.isEmpty()) {
            for (Item item : items) {
                sum += item.getMass();
            }
            return sum / items.size();
        }
        return sum;
    }

    public double getAverageVolume() {
        double sum = 0;

        if (!items.isEmpty()) {
            for (Item item : items) {
                sum += item.getVolume();
            }
            return sum / items.size();
        }
        return sum;
    }
}

正如 Johannes Kuhn 在评论中提出的那样,您可以将 getter 作为 ToDoubleFunction<Item> 传递给您的计算方法:

private double calcAverage(ToDoubleFunction<Item> getter) {
    double sum = 0;

    if (!items.isEmpty()) {
        for (Item item : items) {
            sum += getter.applyAsDouble(item);
        }
        return sum / items.size();
    }
    return sum;
}

public double getAveragePrice() {       
    return calcAverage(Item::getPrice);
}

然后您可以重复使用计算:

public double getAverageMass() {
    return calcAverage(Item::getMass);
}

public double getAverageVolume() {
    return calcAverage(Item::getVolume);
}

这是一个使用流的解决方案API

public double getAverageMass() {
    return calcAverage(Item::getMass);
}

public double getAverageVolume() {
    return calcAverage(Item::getVolume);
}

private double calcAverage(ToDoubleFunction<Item> getter) {
    return items.stream().mapToDouble(getter).average().orElse(0);
}