[英]Is there a list backed by a Map?
我在Swing TreeList中顯示的列表中有100k項。 請參閱jide-demo https://www.jidesoft.com/products/download.htm中的 AutoFilterTreeTableDemo
過濾時,需要很長時間來擴展節點。
分析時,Vector.indexOf()大約需要20秒。 我將其切換到ArrayList,大約花了5秒鍾。
然后,我將列表緩存為Map<Row, Integer>
,其中Integer是列表中的索引。 這樣可以將過濾時間減少到〜0.2s。
但是,如果在中間的某處添加一行,則必須重新構建地圖,因為列表的索引將發生更改。
是否存在使用映射來支持列表索引的數據結構? 還是我必須自己解決這個問題?
另外,是否有一個具有非常快速indexOf時間的普通List? 我不介意在這個費用略有犧牲插入/缺失倍。
第三種選擇是,如果我可以使用更優化的可過濾Swing網格。
編輯:代碼段:
private Map<Row, Integer> rowLookup = new ConcurrentHashMap<Row, Integer>();
@Override
public int getRowIndex(Row row) {
if(rowLookup.isEmpty()) {
List<Row> existingRows = getRows();
for(int i = 0; i < existingRows.size(); i++) {
Row mappingRow = existingRows.get(i);
rowLookup.put(mappingRow, i);
}
}
if(row == null) {
return -1;
} else {
Integer lineNumber = rowLookup.get(row);
if(lineNumber == null) {
lineNumber = -1;
}
return lineNumber;
}
}
我認為您可能正接近最佳解決方案。 您有兩個矛盾的需求:
通常對於(1),您將使用諸如Map或Linked List之類的東西
對於(2),您將使用數組
原因(1)與(2)沖突是,當您執行(1)時,必須更新每個后續項,以便其索引被更新。 我認為您不會找到通用的數據結構來執行此操作,因為它無法高效完成。
我想,如果我是您,除了解決問題(我認為現在不可能)之外,我會做您正在做的事情。
但是,您不應將地圖視為完整的地圖,而應將其用作緩存。
當您執行查找時,再次檢查以確保索引匹配,以及是否未從地圖中清除條目; 找到正確的值; 然后更新地圖,例如
public int getRowIndex(Row row) {
Integer index = rowLookup.get(mappingRow);
List<Row> existingRows = getRows();
if (index != null) {
int i = index.intValue();
if (i < existingRows.size() && row == existingRows.get(i)) {
return i;
}
rowLookup.remove(i);
}
/* Otherwise we'll have to look it up the slow way */
int i = existingRows.indexOf(row);
rowLookup.put(row, i);
return i;
}
對不起,您還沒有嘗試編譯,僅供參考。
您可能希望將其與另一個定期運行的功能配對,以重新構建整個緩存。
並非完全符合您的期望,但可以考慮將其作為您問題的替代解決方案: org.apache.commons.collections.list.TreeList indexOf方法的性能並不優於ArrayList實現,但是對於您的用例,我認為它將可以接受。
此列表實現在內部利用樹結構來確保所有插入和刪除均為O(log n)。
下表是從其文檔中獲取的,以作為與其他List實現相比其性能的度量。 缺點是會消耗更多的內存:
* get add insert iterate remove
* TreeList 3 5 1 2 1
* ArrayList 1 1 40 1 40
* LinkedList 5800 1 350 2 325
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.