我担心这是一个非常愚蠢的问题。但是,我找不到答案,因此需要一些帮助:)
让我们从简化我的真实问题开始:
假设我有几个装满各种宝石的盒子。
我现在正在创建一个具有属性颜色的对象gem和一个getColour方法来获取gem的颜色。 此外,我正在创建一个对象框,其中包含一个gems列表作为属性,另一个方法getGem用于从该列表中获取gem。
我现在要做的是按颜色计算所有框中的所有宝石。现在我可以做像
这样的事情int sapphire = 0;
int ruby = 0;
int emerald = 0;
for(each box = i)
for(each gem = j)
if(i.getGem(j).getColour().equals(“blue”)) sapphire++;
else if(i.getGem(j).getColour().equals(“red”)) ruby++;
else if(i.getGem(j).getColour().equals(“green”)) emerald++;
或者我可以做
int sapphire = 0;
int ruby = 0;
int emerald = 0;
String colour;
for(each box = i)
for(each gem = j)
colour = i.getGem(j).getColour();
if(colour.equals(“blue”)) sapphire++;
else if(colour.equals(“red”)) ruby++;
else if(colour.equals(“green”)) emerald++;
我现在的问题是,两者基本相同还是优先于另一个?我知道在第二种情况下会产生许多不必要的新字符串对象,但是由于颜色更“直接”可用,我是否会获得速度优势?
答案 0 :(得分:2)
我敢于进行第三次改进:
int sapphire = 0;
int ruby = 0;
int emerald = 0;
for(each box = i) {
for(each gem = j) {
String colour = i.getGem(j).getColour();
if(“blue”.equals(colour)) sapphire++;
else if(“red”.equals(colour)) ruby++;
else if(“green”.equals(colour)) emerald++;
}
}
这具有以下优点:更易于阅读且不存在性能问题。如果您遇到性能问题,那么您应该考虑查看代码中的其他位置。与此相关:this answer。
答案 1 :(得分:2)
答案 2 :(得分:1)
字符串比较的成本将消除这种方法中的所有其他注意事项。
您最好使用其他东西(例如enum
)。那也会自动扩大。
(尽管你的每个循环都不是正确的Java语法,所以这有点奇怪)。
enum GemColour {
blue,
red,
green
}
然后在你的计数功能中:
Map<GemColour, Integer> counts = new EnumMap<GemColour, Integer>(GemColour.class);
for (Box b: box) {
for (Gem g: box.getGems() {
Integer count = counts.get(g.getColour());
if (count == null) {
count=1;
} else {
count+=1;
}
counts.put(g.getColour(), count);
}
}
现在它会自动扩展到您添加的任何新颜色,而无需进行任何代码更改。它也会更快,因为它进行单个整数比较而不是字符串比较,并使用它将正确的值放入地图中的正确位置(在幕后只是一个数组)。
要获得计数,例如:
counts.get(GemColour.blue);
正如评论中指出的那样,java Stream API允许你在一行中完成所有这些:
boxes.stream().map(Box::getGems).flatMap(Collection::stream).collect(groupingBy(Gem::getColour, counting()))
虽然不太容易理解它正在做什么。