简体   繁体   English

如何在迭代时添加到 HashMap 内的 ArrayList

[英]How Do I add to an ArrayList within a HashMap while iterating

While following a tutorial series for LWJGL for my file university project, I add game items to the world that have an associated Mesh class,在为我的文件大学项目遵循 LWJGL 教程系列时,我向世界添加了具有关联网格 class 的游戏项目,

If I were to add many objects to the world that shared the same mesh, it would be more efficient to associate a list of game items to one Mesh type and then render from there如果我要向世界添加许多共享相同网格的对象,将游戏项目列表关联到一个网格类型然后从那里渲染会更有效

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);
        }
}

this works perfectly until I try to add new game items to the world while the hashmap is being iterated over, any subsequent calls to addStaticGameItem seems to add the game logic of a new item to the world, but the Mesh is not added properly and thus cannot be seen at all.直到我尝试在 hashmap 被迭代时向世界添加新的游戏项目之前,这一切正常,对 addStaticGameItem 的任何后续调用似乎都会将新项目的游戏逻辑添加到世界,但网格没有正确添加,因此根本看不到。

here's where the hashmap is called for rendering:这里是调用 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);
                }
        );
    }

So how do I properly add new values to a Hashmap list while iterating?那么如何在迭代时正确地将新值添加到 Hashmap 列表中?

EDIT: this works编辑:这有效

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>>();
}

You actually can't add new values to HashMap while iterating.您实际上无法在迭代时向 HashMap 添加新值。 But you may try to create a temporary map tempMap , add new items to this tempMap and then, after iterating, change your original HashMap (u can use meshMap.putAll(tempMap) ).但是您可以尝试创建一个临时的 map tempMap ,向该tempMap添加新项目,然后在迭代后更改您原来的 HashMap (您可以使用meshMap.putAll(tempMap) )。

Also check out HashMap documentation Where you can find另请查看HashMap 文档在哪里可以找到

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.所有此类的“集合视图方法”返回的迭代器都是快速失败的:如果 map 在创建迭代器后的任何时间进行结构修改,除了通过迭代器自己的 remove 方法之外,迭代器将抛出 ConcurrentModificationException .

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM