是否有地图支持的列表?

时间:2017-02-03 15:26:29

标签: java list arraylist

我在Swing TreeList中显示的列表中有100k项。请参阅jide-demo https://www.jidesoft.com/products/download.htm

中的AutoFilterTreeTableDemo

过滤时,需要很长时间才能扩展节点。

在分析时,Vector.indexOf()需要大约20秒。我把它切换到了ArrayList,花了大约5秒钟。

然后我将List缓存为Map<Row, Integer>,其中Integer是列表中的索引。这将滤波减少到~0.2s。

但是,如果我在中间某处添加一行,我必须重建地图,因为列表的索引会发生变化。

是否有使用地图来支持列表索引的数据结构?或者我必须自己管理这个?

或者,是否有正常的List具有非常快的indexOf次?我不介意牺牲插入/删除时间轻微而牺牲了这一点。

第三种选择是如果我可以使用更优化的可过滤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;
        }
    }

2 个答案:

答案 0 :(得分:0)

我认为你可能接近最佳解决方案。你有两个相互矛盾的需求:

  1. 您希望能够随机插入项目
  2. 您希望能够根据固定索引访问这些项目
  3. 通常对于(1)你会使用像地图或链接列表

    这样的东西

    对于(2),您将使用数组

    与(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;
    }
    

    很抱歉没有尝试过编译,这只是说明性的

    您可能希望将其与另一个定期运行的功能配对,以完全重建缓存。

答案 1 :(得分:0)

不完全符合您的要求,但可以将其视为您问题的替代解决方案: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