java - 在 DefaultListModel 与 ConcurrentHashMap 中存储数据

标签 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:

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

一些示例代码:

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 ,带有请求标识符和请求值。我现在可以填充 JListDefaultListModel其中包含 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);
}

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

//No more HashMap
DataHolder holder = (DataHolder)theList.getSelectedValue();

Object request = holder.getData();
//Do something with request

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

更多信息:

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

编辑:

将消息添加到列表的序列现已包含在 invokeLater 中。通过我的实现,每次将消息添加到列表中时,都会创建一个新线程来完成所有工作,并在消息进入列表后结束。这肯定会影响答案。 如果连续创建 50 个线程(每次调用 addToList),哪个解决方案执行速度更快?

最佳答案

解决方案 3:扩展 SwingWorker ,

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

doInBackground() 的实现中,publish() 中间结果可用。在 process() 的实现中,更新 View 组件的模型。方便的是,SwingWorker 将在 sustainable pace 处合并 publish() 调用。 。 Profile您的申请需要验证。更多示例可参见 here .

关于java - 在 DefaultListModel 与 ConcurrentHashMap 中存储数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22629431/

相关文章:

java - jackson 注释中的多态性 : @JsonTypeInfo usage

java - thread.sleep() 的替代方案 - 亚马逊 selenium webdriver 添加到购物车忽略保险对话框

java - BoxLayout 粘在顶部

java - 从 JList 中删除所选项目

java - 使用 List<String> 填充 JList nullpointerException

java - 为运行时生成的 POJO 类添加注解

java - 如何编辑 Spring Pageable 对象?

java - 在 BufferedImage 中绘制多条线

Java如何使用GridBagLayout创建布局?

java - ArrayList for 循环打印索引而不是值