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.
好吧,你可以有类似的东西:
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的答案比我的更具体.这意味着它可以更高效,因为没有必要包装计数 - 当然,更少可重复使用.您决定使用哪种方法是判断调用,这在很大程度上取决于您的实际用例.