【问题标题】:Using Hashtable, Arraylist. Getting info from them使用哈希表、数组列表。从他们那里获取信息
【发布时间】:2012-01-19 12:20:35
【问题描述】:

我有一个包含用户和频道的聊天程序。我的下一个任务是获取一个用户所在频道的列表。应该如何完成?

以下是目前的代码:

ChatFrontImpl:

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

public synchronized boolean registerClient(Client client, String password) throws RemoteException {
if(!u.logIn(client.findName(), password)){
    System.out.println("Wrong username or password!");
    return false;
}
if (!clients.contains(client)) {
    try {
        clients.add(client);
        updateJlist();
        System.out.println(client.findName() + " registered.");
    } 
    catch (Exception e){
        System.out.println("error in method registerClient(): " + e);
    }
    return true;
}else
    return false;
} 

public void connectChannel(String username, String channel) throws RemoteException{ 
    if(isUserRegistered(username)){
        if (!channels.containsKey(channel)) {
            String message = "User " + username + " entered the channel";
            channels.put(channel, new ArrayList<String>());
            channels.get(channel).add(username);
            notifyChannelSystem(channel, "SYSTEM", message);
            notifySelf(username, "Write /? for avaliable commands");
        }
        else{
            if(channels.get(channel).contains(username)){ 
            } 
            else {
                channels.get(channel).add(username);
                String message = "User " + username + " just entered the channel";
                notifyChannelSystem(channel, "SYSTEM", message);        
          }
        }
    }
}

【问题讨论】:

  • 您能否扩展您的问题以包括变量 kanal 的定义。如果 kanal 实际上应该是 channel,则该程序是有意义的。
  • 哦,代码通常是挪威语,但我翻译了(显然只是其中的一部分)。变量应该是通道,只要它说 kanal ofc :)
  • 我更正了变量 + 将方法更改为 void,因为我真的不需要返回

标签: java arraylist hashtable


【解决方案1】:

我会使用不同的数据结构 - 但假设您希望继续使用这个(为了回答问题):

public List<String> getChannelsForUsername(String username) {
    List<String> userChannels = new ArrayList<String>();
    for (String channel : channels.keySet()) {
        if (channels.get(channel).contains(username)) {
            userChannels.add(channel);
        }
    }
    return userChannels;
}

【讨论】:

  • 你确定这行得通吗?我不应该使用枚举来浏览频道列表吗?
  • public List&lt;String&gt; getChannelsForUsername(String username) { List&lt;String&gt; userChannels = new ArrayList&lt;String&gt;(); for (Enumeration e = channels.elements() ; e.hasMoreElements() ;) { if (channels.get(channels).contains(username)) { userChannels.add(channels); } } return userChannels; } 不应该是这样的吗?我遇到了一个可怕的错误。我不允许使用 .add(channels)。但是我可以添加用户名,这有点奇怪
  • foreach 循环将遍历任何可迭代的内容,并且 channels 是一个 HashMap。我将更新我的答案以迭代 Map 的键 - 对此感到抱歉!
【解决方案2】:

有地图

private HashMap<Client, channlesList> clientsAndRooms;
private ArrayList channels = ArrayList <channel>();

我不知道你为什么有 hashTable,我会尽量避免它。

将用户连接到频道时

1) 检查 hasmap 是否已经拥有该用户 您可以获取 keySet 并执行包含。如果存在,则将 channelList 和新频道添加到此列表并再次保存以映射。 2)如果这是第一个频道,

channelList.add(channel);
clientAndRooms.put(userName,channelList);

注意:可能有语法错误,我只是在这里输入的。

【讨论】:

  • 我敢打赌这个结构比我的好?
  • 如果哈希表对业务不利,我可能会尝试更改为此代码
  • Hashtables 是同步的 HashMaps。鉴于您将受到并发性的影响,我会坚持使用 Hashtable 或转向 ConcurrentHashMap。
  • @brainzzy:我同意。如果是并发的话,我还是更喜欢 ConcurrentHashMap。
猜你喜欢
  • 2012-02-17
  • 1970-01-01
  • 2014-02-23
  • 1970-01-01
  • 1970-01-01
  • 2017-01-24
  • 2014-11-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多