Java 在多个地图与一个列表中缓存对象

Java caching objects in several maps vs one list

我目前正在缓存列表 List<CachedObject> 中的数据库对象。 CachedObject 看起来像这样:

class CachedObject
{
    private int id;
    private int id_type;
    private int id_other_type;

    // getters and setters
}

我目前在这个函数中从缓存中获取对象

    public CachedObject getCachedObjectById( Integer id )
    {
        for ( CachedObject cachedObject : cachedObjectList )
            if( id.equals(cachedObject.getId() ) )
                return cachedObject;

        return null;
    }

    public List<CachedObject> getCachedObjectByIdType( Integer idType )
    {
        List<CachedObject> cachedObjectList = new ArrayList<CachedObject>();

        for ( CachedObject cachedObject : this.cachedObjectList )
            if( idType.equals(cachedObject.getIdType() ) )
                cachedObjectList.add(cachedObject);

        return cachedObjectList;
    }

由于这样做了很多,加载缓存以在单独的地图(在本例中为 3)中分发信息时是否会更快:

Map<Integer, CachedObject> cachedObject_to_id
Map<Integer, List<CachedObject>> cachedObjectList_to_idType
Map<Integer, List<CachedObject>> cachedObjectList_to_idOtherType

获取对象时,只需从地图中获取即可。

编辑:

任何不同时间的缓存对象数为 20 - 500。

访问哈希 table 通常比使用顺序扫描方法更快。但是如果只是检查几个值(10个以下),那就无所谓了。

备注:方法 getCachedObjectByIdType returns 一个 mutable 列表。如果客户端代码不受您的控制,您可以将其转换为 immutable 列表。

我稍微倾向于在你的情况下使用地图。原因:

  • 访问速度会更快
  • 访问时间保持不变,不会随着更多数据的到来而变化
  • 访问不需要对象分配。您需要一个用于迭代器,一个用于数组列表。也许另一个将其转换为 immutable 列表。

但是代码变得更加复杂。当您在最坏的情况下必须扫描 500 个对象时,这意味着,通过使用哈希映射,您的代码可以快两个数量级。但是,这可能对应用程序没有影响。要问的问题:

  • 这些对象的访问频率是多少?它是不是非常重要且经常访问的东西?
  • 我真的要对 500 个元素进行额外测试,以检查整体性能是否符合要求table?
  • 我需要多久更新一次缓存并重建数据结构?
  • 完全构建地图还是使用延迟加载?
  • 谁来解决并发问题?地图是否有并发修改,还是只读的?