如何在迭代时添加到 HashMap 中的 ArrayList
How Do I add to an ArrayList within a HashMap while iterating
在为我的文件大学项目遵循 LWJGL 系列教程时,我将游戏项目添加到具有关联网格的世界中 class,
如果我要向世界添加许多共享相同网格的对象,将游戏项目列表关联到一种网格类型然后从那里渲染会更有效
private Map<Mesh, List<GameItem>> meshMap;
meshMap = new HashMap();
public void addDynamicGameItem(DynamicGameItem dynamicGameItem) {
numGameItems++;
Mesh[] meshes = dynamicGameItem.getMeshes();
for(Mesh mesh : meshes) {
List<GameItem> list = tempMap.get(mesh);
if (list == null) {
list = new ArrayList<>();
tempMap.put(mesh, list);
}
list.add(dynamicGameItem);
}
}
在迭代散列图时尝试向世界添加新游戏项目之前,此方法一直有效,对 addStaticGameItem 的任何后续调用似乎都会向世界添加新项目的游戏逻辑,但网格是没有正确添加,因此根本看不到。
这里是调用 hashmap 进行渲染的地方:
Map<Mesh, List<GameItem>> mapMeshes = scene.getGameMeshes();
for (Mesh mesh : mapMeshes.keySet()) {
if(mesh.getMaterial() != null) {
sceneShaderProgram.setUniform("material", mesh.getMaterial());
Texture text = mesh.getMaterial().getTexture();
if (text != null) {
sceneShaderProgram.setUniform("numCols",
text.getNumCols());
sceneShaderProgram.setUniform("numRows",
text.getNumRows());
}
}
mesh.renderList(mapMeshes.get(mesh), (GameItem gameItem) -> {
sceneShaderProgram.setUniform("selected",
gameItem.isSelected() ? 1.0f : 0.0f);
Matrix4f modelViewMatrix =
transformation.buildModelViewMatrix(gameItem,
viewMatrix);
sceneShaderProgram.setUniform("modelViewMatrix",
modelViewMatrix);
Matrix4f modelLightViewMatrix =
transformation.buildModelLightViewMatrix(gameItem,
lightViewMatrix);
sceneShaderProgram.setUniform("modelLightViewMatrix",
modelLightViewMatrix);
}
);
}
那么如何在迭代时正确地将新值添加到 Hashmap 列表?
编辑:有效
public void updateMeshMap(){
if(!tempMap.isEmpty()){
for(Mesh m : tempMap.keySet()){
List list = meshMap.get(m);
if (list == null) {
list = new ArrayList<>();
list.addAll(tempMap.get(m));
meshMap.put(m, list);
}else{
list.addAll(tempMap.get(m));
}
}
}
tempMap = new HashMap<Mesh, List<GameItem>>();
}
您实际上不能在迭代时向 HashMap 添加新值。但是你可以尝试创建一个临时映射tempMap
,向这个tempMap
添加新的项目,然后在迭代之后,改变你原来的HashMap(你可以使用meshMap.putAll(tempMap)
)。
另请查看 HashMap documentation
在哪里可以找到
The iterators returned by all of this class's "collection view
methods" are fail-fast: if the map is structurally modified at any
time after the iterator is created, in any way except through the
iterator's own remove method, the iterator will throw a
ConcurrentModificationException.
在为我的文件大学项目遵循 LWJGL 系列教程时,我将游戏项目添加到具有关联网格的世界中 class,
如果我要向世界添加许多共享相同网格的对象,将游戏项目列表关联到一种网格类型然后从那里渲染会更有效
private Map<Mesh, List<GameItem>> meshMap;
meshMap = new HashMap();
public void addDynamicGameItem(DynamicGameItem dynamicGameItem) {
numGameItems++;
Mesh[] meshes = dynamicGameItem.getMeshes();
for(Mesh mesh : meshes) {
List<GameItem> list = tempMap.get(mesh);
if (list == null) {
list = new ArrayList<>();
tempMap.put(mesh, list);
}
list.add(dynamicGameItem);
}
}
在迭代散列图时尝试向世界添加新游戏项目之前,此方法一直有效,对 addStaticGameItem 的任何后续调用似乎都会向世界添加新项目的游戏逻辑,但网格是没有正确添加,因此根本看不到。
这里是调用 hashmap 进行渲染的地方:
Map<Mesh, List<GameItem>> mapMeshes = scene.getGameMeshes();
for (Mesh mesh : mapMeshes.keySet()) {
if(mesh.getMaterial() != null) {
sceneShaderProgram.setUniform("material", mesh.getMaterial());
Texture text = mesh.getMaterial().getTexture();
if (text != null) {
sceneShaderProgram.setUniform("numCols",
text.getNumCols());
sceneShaderProgram.setUniform("numRows",
text.getNumRows());
}
}
mesh.renderList(mapMeshes.get(mesh), (GameItem gameItem) -> {
sceneShaderProgram.setUniform("selected",
gameItem.isSelected() ? 1.0f : 0.0f);
Matrix4f modelViewMatrix =
transformation.buildModelViewMatrix(gameItem,
viewMatrix);
sceneShaderProgram.setUniform("modelViewMatrix",
modelViewMatrix);
Matrix4f modelLightViewMatrix =
transformation.buildModelLightViewMatrix(gameItem,
lightViewMatrix);
sceneShaderProgram.setUniform("modelLightViewMatrix",
modelLightViewMatrix);
}
);
}
那么如何在迭代时正确地将新值添加到 Hashmap 列表?
编辑:有效
public void updateMeshMap(){
if(!tempMap.isEmpty()){
for(Mesh m : tempMap.keySet()){
List list = meshMap.get(m);
if (list == null) {
list = new ArrayList<>();
list.addAll(tempMap.get(m));
meshMap.put(m, list);
}else{
list.addAll(tempMap.get(m));
}
}
}
tempMap = new HashMap<Mesh, List<GameItem>>();
}
您实际上不能在迭代时向 HashMap 添加新值。但是你可以尝试创建一个临时映射tempMap
,向这个tempMap
添加新的项目,然后在迭代之后,改变你原来的HashMap(你可以使用meshMap.putAll(tempMap)
)。
另请查看 HashMap documentation 在哪里可以找到
The iterators returned by all of this class's "collection view methods" are fail-fast: if the map is structurally modified at any time after the iterator is created, in any way except through the iterator's own remove method, the iterator will throw a ConcurrentModificationException.