一些哈希表问题。从哈希表中删除对象

时间:2012-01-23 17:24:29

标签: java hashtable

我在向渠道主义者移除客户时遇到了一些问题。

这是我目前的代码:

了Serverside:

private Hashtable<String, ArrayList<String>> channels = new Hashtable<String, ArrayList<String>>();

    public synchronized void logMeOut(String username) throws RemoteException {
        for(Client c : clients){
            if(c.findName().equals(username)){
                clients.remove(c);
                disconnectAllChans(username);
                System.out.println(username + " removed from clientlist.");
            }
        }
        updateJListForOnlineUsers(); //Callback for other clients to update the userlist.
    }

  public void disconnectAllChans(String username) throws RemoteException{
    for(Enumeration e = channels.elements(); e.hasMoreElements();){
        if(channels.contains(username)){
            channels.remove(username);
        }
    }
    updateJListForUsersInChannel();
    System.out.println("User " + username + " left all channel");
}

我已经尝试了两个if(channels.contains(用户名)和containsKey。他们似乎都没有做这项工作。当我离开运行注销方法的服务器时,客户端就会挂起。我猜它是在Enumeration循环中进行everloop。

编辑:客户端仅在加入频道时挂起。如果用户的channellist为空,则会立即退出。

代码看起来应该是什么想法?

**

解决方案:

**

所以是的,我想出来了,但没有你们,我就没有。感谢

我刚刚在断开所有通道方法中运行了disconnectmethod,这种方法已经发布了。结果如下:

@Override
public void disconnectChannel(String username, String channel) throws RemoteException{
    if(isUserInChannelX(username, channel)){
        channels.get(channel).remove(username);
        String message = "User " + username + " left the channel.";
        notifySelf(username, " You have left the channel " + channel);
        notifyChannelSystem(channel, "SYSTEM", message);
        updateJListForActiveChannels();
        if(channels.get(channel).isEmpty()){
            channels.remove(channel);
        } 
    }
}

public void disconnectAllChans(String username) throws RemoteException{
    for (String channel : channels.keySet()) {
    ArrayList<String> members = channels.get(channel);
        if (members.contains(username)) {
            disconnectChannel(username, channel);
            System.out.println("User " + username + " left channel " + channel);
        }
    }
    updateJListForUsersInChannel();
}

我觉得有点傻^^谢谢大家!

2 个答案:

答案 0 :(得分:5)

你的代码中有一个无限循环:

for(Enumeration e = channels.elements(); e.hasMoreElements();){
    if(channels.contains(username)){
        channels.remove(username);
    }
}

您永远不会从枚举e中删除元素,因此e.hasMoreElements将始终返回true。你可能想要更像这样的东西:

ArrayList<String> channel = null;
for(Enumeration e = channels.elements(); e.hasMoreElements(); channel = e.nextElement()){
    if(channel.contains(username)){
        channel.remove(username);
    }
}

作为旁注,您将使用当前代码遇到并发修改错误。

答案 1 :(得分:2)

用foreach循环替换for,让你更难以制造无限循环错误,就像你没有正确处理枚举器一样:

for (String channel : channels.keySet()) {
    ArrayList<String> members = channels.get(channel);
    if (members.contains(username)) {
        members.remove(username);
    }
}

我认为你会做你想做的事。