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

发布于 2024-12-28 15:51:26 字数 2272 浏览 1 评论 0原文

我在从频道列表中删除客户端时遇到一些问题。

这是我目前的代码:

服务器端:

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(username) 和 containsKey。它们似乎都不起作用。当我离开服务器时,运行注销方法,我猜

客户端会在该枚举循环中挂起:如果用户的频道列表为空,则客户端只会挂起。有

什么想法吗?

**

解决方案:

**

所以,是的,我想通了,但如果没有你们,我就不会这样做。谢谢,

我刚刚在 Brainzzy 发布的断开所有通道方法中运行了断开连接方法。结果如下:

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

我觉得有点愚蠢^^谢谢大家!

I'm having some problems removing clients from a channellist.

This is the code i have at the moment:

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

I have tried both if(channels.contains(username), and containsKey. None of them seems to do the work. When i leave the server, which runs the logout method, the client just hangs. I'm guessing its going on a foreverloop in that Enumeration loop.

EDIT: The client only hangs IF it has joined a channel. If the channellist for a user is empty, it quits right away.

Any ideas how the code should look?

**

Solution:

**

So yeah, i figured it out, but i wouldn't have without you guys. Thanks

I just ran the disconnectmethod inside the disconnect all channels method which brainzzy posted. Heres the result:

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

I feel kinda stupid ^^ Thanks people!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

李白 2025-01-04 15:51:26

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

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

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

You have an infinite loop in your code:

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

You never take an element off Enumeration e, so e.hasMoreElements will always return true. You probably want something more like this:

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

As a side note, you're going to run into concurrent modification errors with your current code.

我不会写诗 2025-01-04 15:51:26

将 for 替换为 foreach 循环,使您更难犯无限循环错误,就像您因未正确处理枚举器而陷入的错误一样:

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

我认为这会做您想要的事情。

Replace the for with a foreach loop, makes it harder to make infinite loop errors like you've got yourself into by not handling the enumerator correctly:

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

I think that'll do what you want it to.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文