Java 在Guava缓存中查找间隔中的记录

Java 在Guava缓存中查找间隔中的记录,java,caching,guava,google-guava-cache,Java,Caching,Guava,Google Guava Cache,我正在用SpringSpel计算一些结果,我想缓存这些结果,这样我就不必用相同的参数计算表达式 我的缓存密钥对象: @Data @AllArgsConstructor public class CachedResult { private String baseName; private Interval interval; public boolean isBetweenInclusive(final DateTime date) { return i

我正在用SpringSpel计算一些结果,我想缓存这些结果,这样我就不必用相同的参数计算表达式

我的缓存密钥对象:

@Data
@AllArgsConstructor
public class CachedResult {
    private String baseName;
    private Interval interval;

    public boolean isBetweenInclusive(final DateTime date) {
        return interval.contains(date) || interval.getEnd().isEqual(date);
    }
}
查找包含给定日期时间的间隔为
的记录的解决方案:

public String getEvaluatedResult(final String baseName, final DateTime dateTime) {
    return cache.asMap().entrySet()
            .stream()
            .filter(entry -> entry.getKey().getBaseName().equals(baseName) && entry.getKey().isBetweenInclusive(dateTime))
            .findFirst()
            .map(Map.Entry::getValue)
            .orElse(null);
}
我想使用
cache.get(key,valueLoader)
方法,这样它就可以在需要时将值放入缓存本身,但我想不出一种方法来利用
is介于inclusive
和此方法之间

我试图在评论中指出我遇到的问题:

public class MyCache {

    private final Cache<CachedResult, String> cache;

    public DefaultRolloverCache(final int expiration) {
        this.cache = CacheBuilder.newBuilder()
                .expireAfterWrite(expiration, TimeUnit.MINUTES)
                .build();
    }

    public String getFileName(final String baseName, final DateTime dateTime, final Callable<String> valueLoader) {
        try {
            return cache.get(new CachedResult(baseName, null/*How to find an interval that covers the given dateTime?*/), valueLoader);
        } catch (final ExecutionException e) {
            throw new IllegalArgumentException(String.format("Cannot read fileName from cache with basename: '%s' and dateTime: %s", baseName, dateTime), e);
        }
    }
}
当然,由于我不知道如何使用上面提到的方法,我必须使用
cache.put(new CachedResult(…)
将记录放入缓存中

有没有比调用
asMap
并像映射一样过滤缓存更好的方法?我是否可以使用
cache.get(key,valueLoader)
或Guavas
CacheLoader
自动输入值


随着演出的进行,我一次最多会有5-10条记录,但我会从中读到很多东西,因此,读取时间对我来说非常重要,我不确定我当前的实现是否是最好的方法,即始终迭代5-10条记录并检查每一条记录。

在阅读Louis的评论后,我的最终解决方案写道:

public String getFileName(final String baseName, final DateTime dateTime, final Supplier<String> valueLoader) {
    final Optional<String> cached = cache.asMap().entrySet()
            .stream()
            .filter(entry -> entry.getKey().getBaseName().equals(baseName) && entry.getKey().isBetweenInclusive(dateTime))
            .findFirst()
            .map(Map.Entry::getValue);

    if (cached.isPresent()) {
        return cached.get();
    } else {
        final String evaluatedValue = valueLoader.get();
        cache.put(new CachedResult(baseName, intervalCalculator.getInterval(dateTime)), evaluatedValue);
        return evaluatedValue;
    }
}
public String getFileName(最终字符串baseName、最终日期时间DateTime、最终供应商值加载器){
最终可选缓存=cache.asMap().entrySet()
.stream()
.filter(entry->entry.getKey().getBaseName().equals(baseName)和&entry.getKey().isBetweenInclusive(dateTime))
.findFirst()
.map(map.Entry::getValue);
if(cached.isPresent()){
返回cached.get();
}否则{
最终字符串evaluatedValue=valueLoader.get();
put(新的CachedResult(baseName,intervalCalculator.getInterval(dateTime)),evaluatedValue);
返回评估值;
}
}

;对5-10条记录进行迭代将非常快,基本上其他任何记录都会比较慢(而且可能没有更好的方法)。调用
asMap
后对映射项进行迭代是否会对过期产生不同于调用
缓存的影响。get
会吗?换句话说,如果缓存中有1条记录,这两个调用是否相同:
cache.asMap().entrySet().stream().findFirst().get().getValue()
cache.get(记录)
public String getFileName(final String baseName, final DateTime dateTime, final Supplier<String> valueLoader) {
    final Optional<String> cached = cache.asMap().entrySet()
            .stream()
            .filter(entry -> entry.getKey().getBaseName().equals(baseName) && entry.getKey().isBetweenInclusive(dateTime))
            .findFirst()
            .map(Map.Entry::getValue);

    if (cached.isPresent()) {
        return cached.get();
    } else {
        final String evaluatedValue = valueLoader.get();
        cache.put(new CachedResult(baseName, intervalCalculator.getInterval(dateTime)), evaluatedValue);
        return evaluatedValue;
    }
}