简体   繁体   English

迭代器,列表迭代器和列表

[英]Iterator, ListIterator and List

I have encountered a problem that I cannot quite figure out. 我遇到了一个我无法完全解决的问题。 Would be super if you guys could help me out =) 如果你们可以帮助我,那就太好了=)

I have a Lobby.Class that has a draw() Method: 我有一个具有draw()方法的Lobby.Class:

public void draw() {
    //USE ITERATOR TO DRAW
    Iterator<Player> itr = players.iterator();
    while(itr.hasNext()) {
        Player player = itr.next();
        int off = players.indexOf(player); //THE CORRECT HEIGHT
        player.draw(off);
    }
}  

Note that this is a server/client game 请注意,这是服务器/客户端游戏

The Lobby.Class has also 1 method called addPlayer() Lobby.Class也有一种称为addPlayer()的方法

public void addPlayer(String _playerName, String _class, String _string_id) {

    int _id = Integer.parseInt(_string_id);

    //CREATE THE NEW PLAYER
    Player new_player = new Player(x, y, _id, _playerName, _class);

    //IF THIS PLAYER IS ME
    if(new_player.getID() == id) {

        me = new_player;

    } else {

        //TELL THE NEW PLAYER I EXIST
        ClientValue.getClient().iExist(_id);

                    //THIS WILL SEND TO CLIENT THAT WILL SEND TO THE SERVER
                    //THAT WILL LOOK FOR THE ID AND SEND TO CLIENT OF THAT ID
                    //AND THE CLIENT WILL SEND TO LOBBY UPDATE PLAYERS()
    }

    players.add(new_player);

    chat.appendChat(chat.joinString(_playerName, _class));
}

The Lobby.Class has also 1 method called updatePlayers() Lobby.Class也有1个称为updatePlayers()的方法

public void updatePlayers(String _playerName, String _class, String _string_id) {

    //THIS IS CALLED WHEN THE SERVER TELLS THIS PLAYER
    //ABOUT OTHER PLAYERS

    int _id = Integer.parseInt(_string_id);

    //CREATE THE NEW PLAYER
    Player new_player = new Player(x, y, _id, _playerName, _class);
    players.add(new_player);

}

Now my problem is the players List, when I enter the lobby addPlayer() will Run at the same time when 2 players join, or when the updatePlayers() are run with addPlayer() 现在我的问题是球员名单,当我进入大厅addPlayer()将在同一时间运行在2个玩家加入,或者当updatePlayers()与运行addPlayer()

The Exception i get is: ConcurrentModificationException 我得到的异常是: ConcurrentModificationException

I am missing two methods, 1 for adding players with an Iterator if possible, 1 for removing players . 我缺少两种方法,一种是在可能的情况下使用迭代器添加播放器,另一种是删除播放器 So that I wont get the error for modifying the players List while going trough it or adding/removing it. 这样我就不会在通过或添加/删除播放器列表时收到修改播放器列表的错误。

I have tried puzzling around with Iteror and ListIterator, but as I have never used them before, I am not sure what to do. 我曾尝试过弄乱Iteror和ListIterator,但由于我以前从未使用过它们,因此我不确定该怎么做。 I need some advice on how to do this. 我需要一些有关如何执行此操作的建议。 Many thanks in advance =) 提前非常感谢=)

Solution: 解:

private List<Player> players = Collections.synchronizedList(new ArrayList<Player>());

    public synchronized void playersList(String cmd, Player _player) {

    Iterator<Player> itr = players.iterator();

    if(cmd.equals("draw")) {

        while(itr.hasNext()) {

            Player player = itr.next();
            int off = players.indexOf(player);
            player.draw(off);
        }

    } else if(cmd.equals("add")) {

        players.add(_player);

    } else if(cmd.equals("remove")) {

        players.remove(_player);
    }
}

You need to synchronise access to the list, allowing only one thread to access the list at a time. 您需要同步对列表的访问,一次只允许一个线程访问列表。

You could use a synchronized block around each access point (including the entire paint method) or you could wrap the player list in a thread safe list using Collections#synchronizedList or, instead of an iterator, you could use the toArray method of players 您可以在每个访问点周围使用synchronized块(包括整个paint方法),也可以使用Collections#synchronizedList将播放器列表包装在线程安全列表中,或者可以使用播放器的toArray方法来代替迭代器

Player[] arrayOfPlayers = players.toArray(new Player[players.size()]);

You are still going to synchronized the this call, but your only locking one line, not a whole loop 您仍将synchronized此调用,但是您只能锁定一行,而不是整个循环

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

相关问题 ListIterator或Iterator不会在列表末尾停止 - ListIterator or Iterator does not stop at the end of the List 可以安全地将ListIterator替换为Iterator吗? (为列表实现CopyOnWrite包装器) - Can ListIterator safely be susbtituted for Iterator? (Implementing a CopyOnWrite wrapper for List) 在Java的列表界面中需要使用listIterator()和iterator()是什么? - what is the need to have listIterator() and iterator() in the list interface in Java? Java ListIterator / Iterator类型 - Java ListIterator/Iterator Type 迭代器和列表迭代器的区别? - Difference between Iterator and Listiterator? 通过 ListIterator 反转列表 - Reversing a List via ListIterator 对ArrayList使用Iterator而不是ListIterator有什么好处? - What is the benefit of using Iterator instead of ListIterator for ArrayList? 如何在listIterator()实现中使用超类iterator()? - How to use super class iterator() in the listIterator() implementation? for (ListIterator<E> it = listIterator(); it.hasNext(); ) VS for (ListIterator<E> it = list.listIterator(); it.hasNext(); ) - for (ListIterator<E> it = listIterator(); it.hasNext(); ) VS for (ListIterator<E> it = list.listIterator(); it.hasNext(); ) 编写一个反映Java内置Iterator的ListIterator - Writing a ListIterator that mirrors Java's built in Iterator
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM