Использование Google Guava CacheLoader для пользовательского класса в качестве ключа

#java #guava

#java #guava

Вопрос:

Я пытаюсь использовать Google Guava CacheLoader для пользовательского класса в качестве ключа.

 @Value.Immutable
public interface RecordAggregatorRequest {
    String name();

    String date();
}


private final LoadingCache<RecordAggregatorRequest, Map<String, Record>> recordsCache = CacheBuilder.newBuilder()
            .expireAfterWrite(Duration.ofMinutes(30))
            .build(CacheLoader.from(recordAggregator::getRecords));
 

А затем вызов, как:

 final Map<String, Record> recordsMap = recordsCache.get(aggregatorRequest);
 

recordAggregator::getRecords вызывается каждый раз. Я подозреваю, что это связано с тем, что хэш-код для RecordAggregatorRequest ключа каждый раз отличается, даже если значения элементов одинаковы. Есть ли способ заставить его работать для пользовательского класса в качестве ключа?

Комментарии:

1. Вы пытались исправить свою логику хэш-кода, чтобы она не была «разной каждый раз»?

2. В настоящее время я не написал никакой логики для вычисления хэша. Вроде как полагаюсь на Google Guava, чтобы сделать это за меня (что не работает)

Ответ №1:

Вы должны реализовать соответствующие методы hashcode и equals в своем пользовательском классе Java.

Guava не понимает внутренних деталей вашего класса и полагается на значимые реализации equals и hashcode . Эти объекты также должны быть эффективно неизменяемыми после их добавления в кеш, иначе могут произойти плохие вещи.

Большинство генераторов кода могут генерировать для вас хорошие значения equals / hashcodes, или вы также можете использовать автозаполнение.

Комментарии:

1. Спасибо за ответ! В моем случае ключ является неизменяемым интерфейсом. Таким образом, equals и переопределение хэш-кода здесь не будут работать. Есть ли способ заставить его работать над этим?

2. Почему у вас не было бы правильного equals и hashCode для неизменяемого типа? Похоже, проблема в @Value.Immutable .

3. Вы имеете в виду, что Google Guava должен вычислять один и тот же хэш-код для разных объектов с одинаковыми значениями элементов?

4. Если @Value.Immutable происходит из immutables.io , затем он вычисляет хэш-код и правильно равняется (на основе свойств объекта, которые в данном случае являются строками).