简体   繁体   中英

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,

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.

here's where the hashmap is called for rendering:

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?

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. 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) ).

Also check out HashMap documentation Where you can find

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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