提供字段访问器方法作为参数

Rin*_*nce 1 java

G'day同志.我有个问题.

我有两种完全重复的方法,除了它们访问不同的字段.我无法将字段值作为参数传递,因为访问发生在循环内(简化示例):

   public final class Thing {

        ImmutableList<Box> boxes;

        public int getNumberOfApples() {
            int total = 0;
            for (Box box : boxes) {
                total += box.getApplesCount();
            }
            return total;
        }

        public int getNumberOfPears() {
            int total = 0;
            for (Box box : boxes) {
                total += box.getPearsCount();
            }
            return total;
        }
    }
Run Code Online (Sandbox Code Playgroud)

我可以将我的水果放入地图并将字段名称作为参数传递,但它看起来很脏,我对当前的课程构成非常满意.所以问题是 - 如何重构我的代码以获得单一的类型方法:

public int getNumberOfFruit(SomethingMagic) {
    moreMagic;
    return total;
}
Run Code Online (Sandbox Code Playgroud)

Cheerio.

Jon*_*eet 6

好吧,你可以有类似的东西:

public interface Function<In, Out> {
    Out apply(In input);
}
Run Code Online (Sandbox Code Playgroud)

然后:

public int getCount(Function<Box, Integer> projection) {
    int total = 0;
    for (Box box : boxes) {
        total += projection(box);
    }
    return total;
}
Run Code Online (Sandbox Code Playgroud)

目前构建该投影将是丑陋的,例如

int pears = thing.getCount(new Function<Box, Integer>() {
    @Override public Integer apply(Box input) {
        return box.getPearsCount();
    }
});
Run Code Online (Sandbox Code Playgroud)

但是在Java 8中,使用lambda表达式会更简单:

int pears = thing.getCount(box -> box.getPearsCount());
Run Code Online (Sandbox Code Playgroud)

请注意,通过使界面非通用,Raffaele Rossi的答案比我的更具体.这意味着它可以更高效,因为没有必要包装计数 - 当然,更少可重复使用.您决定使用哪种方法是判断调用,这在很大程度上取决于您的实际用例.