[英]Storing Data in DefaultListModel vs ConcurrentHashMap
我正在用 Swing 編寫一個 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
。 我現在可以使用包含DataHolder
DefaultListModel
填充JList
,並且不需要引用任何其他數據結構來檢索實際請求值。 因為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
哪種解決方案會產生更快的結果? 有沒有更有效的方法來做到這一點? 對此事的任何幫助將不勝感激。
更多信息:
編輯:
將消息添加到列表的序列現在已包含在invokeLater
。 在我的實現中,每次將消息添加到列表中時,都會創建一個新線程來完成所有工作,並在消息進入列表后結束。 這肯定會影響答案。 如果連續創建 50 個線程(每次調用 addToList),哪個解決方案執行得更快?
解決方案 3:擴展SwingWorker
,
class MessageWorker extends SwingWorker<List<DataHolder>, DataHolder> {}
在doInBackground()
實現中, publish()
中間結果可用。 在process()
實現中,更新視圖組件的模型。 方便的是, SwingWorker
將以可持續的速度合並publish()
調用。 配置您的應用程序以進行驗證。 可以在此處找到更多示例。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.