在DefaultListModel和ConcurrentHashMap中存储数据

时间:2014-03-25 08:51:20

标签: java swing jlist concurrenthashmap defaultlistmodel

我正在编写一个用于显示来自客户端的请求的GUI。服务器填充LinkedBlockingQueue,而另一个线程在有可用数据时从队列中获取。请求存储为Object。像这样:

while(should_take) {
    //getRequest() is blocking
    Object request = server.getRequest();

    //Add request to user interface
    GUI.addToList(request);
}

现在我的问题出现了,是否会更好:

解决方案1:

request存储在ConcurrentHashMap<Integer, Object>中,其中密钥作为请求的哈希值,值作为对象。然后,我将使用DefaultListModel来存储请求的标识符(例如,请求类型)和哈希值。 DefaultListModel将用于填充JList,有效地向用户显示请求。然后,可以使用DefaultListModel中保存的哈希从ConcurrentHashMap中检索所选请求(由用户选择)的值。

一些示例代码:

ConcurrentHashMap<Integer, Object> requests = new ConcurrentHashMap<>();
DefaultListModel listData = new DefaultListModel();
JList theList = new JList();
...
public void addToList(Object request) {
    //Place in HashMap
    requests.put(request.hashCode(), request);

    //Create a DataHolder with the Hashvalue and identifier of the request
    DataHolder holder = new DataHolder(request.getID(), request.hash);

    //Add the element to the ListModel
    listData.addElement(holder);

    //Assign the list model to the JList
    theList.setModel(listData);
}

当用户选择列表中的项目时:

DataHolder holder = (DataHolder)theList.getSelectedValue();
//Get request from HashMap

Object request = requests.get(holder.getHash());
//Do something with request

解决方案2:

我使用请求标识符和请求值填充新对象,称之为DataHolder。我现在可以使用包含JList的{​​{1}}填充DefaultListModel,并且不需要任何其他数据结构的引用来检索实际的请求值。因为DataHolder用于填充DefaultListModel,我觉得它会影响性能并可能导致列表填充/填充速度变慢。

一些示例代码:

JList

当用户选择列表中的项目时:

DefaultListModel listData = new DefaultListModel();
JList theList = new JList();
...
public void addToList(Object request) {
    //Removed HashMap

    //Create a DataHolder with the Hashvalue and *actual value* of the request
    DataHolder holder = new DataHolder(request.getID(), request);

    //Add the element to the ListModel
    listData.addElement(holder);

    //Assign the list model to the JList
    theList.setModel(listData);
}

哪种解决方案会产生更快的结果?有没有更有效的方法来做到这一点?任何有关此事的帮助将不胜感激。

更多信息:

  • 请求可能会以突发方式发送。 (每次爆发50+)
  • 请求将包含20到50行XML
  • 将从数据结构中随机删除请求

编辑:

将消息添加到列表的序列现在已包含在//No more HashMap DataHolder holder = (DataHolder)theList.getSelectedValue(); Object request = holder.getData(); //Do something with request 中。通过我的实现,每次将消息添加到列表中时,将创建一个新线程来完成所有工作,并在消息在列表中时结束。当然这会影响答案。 如果连续创建50个线程(每次调用addToList),哪个解决方案会更快执行?

1 个答案:

答案 0 :(得分:2)

解决方案3:扩展SwingWorker

class MessageWorker extends SwingWorker<List<DataHolder>, DataHolder> {}

doInBackground()publish()中间结果的实施中,它们可用。在process()的实施中,更新视图组件的模型。方便的是,SwingWorker会在sustainable pace合并publish()次调用。 Profile您的申请需要验证。可以找到更多示例here