有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java缓存集时最好的标识符是什么?什么时候对集合进行hashCode计算?

实现集合缓存的最佳方法是什么?特别是,什么是缓存的最佳密钥

在静态工厂方法中,我希望包含一个缓存机制,以便可以重用现有(不可变)对象。这种重用不应该带来显著的性能损失。此类的关键数据是参数化LinkedHashSet。我想知道使用这个集合的hashCode作为缓存的键(HashMap)是否明智,因为在java文档中它说: “集合的哈希代码定义为集合中元素的哈希代码之和”。 这难道不是一个缓慢的过程吗?什么时候算?一旦集合生成或按需生成?这难道不能消耗掉我期望通过缓存获得的大量性能收益吗

此外,hashCode是一个int,但HashMaps不接受原语,所以这需要装箱到整数,对吗

我目前的方法是,保持现有对象集合的额外长度集合。工厂方法首先检查当前集合的长度是否已列出,然后才在实际索引中查找。但这也包括拳击

有更好的解决办法吗


共 (2) 个答案

  1. # 1 楼答案

    您需要使用一些不变量作为每个集合的键,逻辑上定义该集合的内容

    考虑创建一个^ {CD1>},要么用一个简单的委托程序包装现有的SET实现,要么对它进行子类化(如果不是最终的)。然后,您可以提供一个附加的键或名称字段来标识集合,并将其用作缓存的键

  2. # 2 楼答案

    Isn't this potentially a slow process? When is it calculated? As soon as the Set is generated or on demand? Couldn't this actually eat up lots the performance gains I expect to gain by caching?

    原则上,这在Set接口中没有指定,因此取决于实现

    对于java.utiljava.util.concurrent(以及通用地图的集合视图)中的通用集合实现,hashCode()是按需计算的,而对于较大的集合,将较慢。(对于具有简单元素的小集合,这并不重要。)

    原因是定义的hashCode(以及equals)是动态的,例如,每当添加或删除元素时都会发生更改,并且如果元素的哈希代码发生更改(这对于基于哈希的集本身是有问题的),也会发生更改。因此,通常情况下,集合/列表/映射并不是映射的好键

    对于不可变集(实际上也是唯一真正适合作为映射键的集类型),哈希代码可以计算一次(在创建时或第一次使用时),然后缓存(就像String那样)

    也可以为可变集实现这种缓存,只要元素的哈希代码不变:公式足够简单,可以在每次添加或删除时更新值,而无需检查添加/删除的元素以外的任何内容。但请确保该集在用作地图中的关键点时不会更改

    (其中大部分也适用于具有类似hashCode()公式的列表和映射。)