【发布时间】:2021-03-23 01:41:09
【问题描述】:
在分析我的 android 游戏后,我注意到在我在整个主游戏循环中调用的简单迭代过程中生成的 ConcurrentHashmap 数量异常。代码如下
public void checkIfStillNeedsToShowUI() {
for (Map.Entry<String, GameUI> gameUIEntry : listOfUIObjects.entrySet()) {
if(!gameUIEntry.getValue().isShowing()){//ignore what not showing
continue;
}
final GameUI tmpGameUI = (gameUIEntry.getValue());
if(!tmpGameUI.hasReasonForShowing()){
continue;
}
if(tmpGameUI.reasonForShowing.checkReason()){
tmpGameUI.setShowing(true);
} else {
tmpGameUI.setShowing(false);
}
}
}
这正常吗?还是我做错了什么?我知道使用通用/增强的 for 循环类型会导致创建一个对象以便访问它,但我目前不知道另一种迭代哈希图的方法,它会给我想要的结果。
【问题讨论】:
-
使用
Map.forEach代替for (entry : entrySet())可能会减少分配的数量,但您可能无法将其归零。 -
有趣的是,对象被命名为
listOfUIObjects,但实际上是Map。 -
@LouisWasserman 试一试。可悲的是,我不得不将我的最小 API 提高到 24。
-
答案是,不,你没有做错任何事,但不可能在不分配对象的情况下迭代 ConcurrentHashMap。遗憾的是,JDK api 确实经常分配对象。在我的工作场所,我们编写零分配 java,但我们通过创建自己的地图实现来实现,该实现具有可重用的迭代器实例,可以在使用前重置。如果您完全有可能只使用一个线程来读/写,那么编写自己的不分配的单线程映射实现会容易得多。祝你好运。
-
查看这个库,了解出色的单线程快速非分配集合实现,包括映射:github.com/real-logic/agrona。对象到对象映射实现在这里:github.com/real-logic/agrona/blob/master/agrona/src/main/java/….
标签: java android loops optimization hashmap