[英]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.