Custom ist gleich/hash beim einfügen Taste (Guava Cache)
Einfach, ich habe zu überschreiben, die Art und Weise, in der der cache wählt die rechts-Taste, da einige Felder (z.B. timestamp, message-id, etc.) sollte nicht sein, als beim abrufen einer Taste.
Kann ich nicht ändern die eigentliche hash-Funktion der Schlüssel Objekt, da es bereits verwendet, um zu erkennen in meinem code.
Ist es moeglich mit Guave-Caches? Und mit einem workaround?
Das ist meine Konfiguration:
CacheBuilder.newBuilder().maximumSize(CACHE_SIZE).recordStats().
expireAfterWrite(DEFAULT_AGE, TimeUnit.DAYS).build(
new CacheLoader<Request, Response>() {
@Override
public Response load(Request request) {
return request.getResponse();
}
});
Und das ist mein hash-Funktion (früher woanders in meinem code):
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + code;
result = prime * result + messageID; //<= **this one shouldn't evaluated**
result = prime * result + Arrays.hashCode(payload);
result = prime * result + (int) (timestamp ^ timestamp >>> 32); //<= **this one shouldn't evaluated**
result = prime * result + (type == null ? 0 : type.hashCode());
result = prime * result + version;
return result;
}
Btw, ist diese Art von cache mit einer eigenen Implementierung der hash-Funktion (z.B. durch Introspektion), oder ist es mit der Standard ein?
** EDIT: **
Wie bereits in den Antworten, der beste Weg, um dieses Ergebnis zu erreichen ist eine wrapper-Klasse.
Meine Lösung:
/**
* Nested class to store a request as a key in the cache. It is needed to
* normalize the variable fields of the normal requests.
*/
private static final class CachedRequest extends Request {
private static CachedRequest fromRequest(Request request) {
//set only the fields that cannot change between two same requests
//...
}
@Override
public int hashCode() {
HashFunction hashFunction = Hashing.md5();
HashCode hashCode;
//...
return hashCode.asInt();
}
@Override
public boolean equals(Object obj) {
//coherent with hashCode()
//...
}
}
- ich kann mir nicht vorstellen, es wäre ein sehr nützliches Dienstprogramm, wenn es verwendet seine eigenen hash-Implementierung.
- außerdem, kannst du näher erklären was du meinst mit "kann ich nicht ändern, meine hash () - Funktion, da Sie bereits verwendet wird, zu erkennen, "echte" equals Objekte."?
- In der Tat, ich verlange nicht, dieses feature hinzufügen, aber wenn jemand weiß, wie man mit dieser situation umgehen.
- Sie mit dieser situation umgehen, indem implementating hashCode() und equals() passend auf den Schlüssel (D. H. Ihrer Anfrage).
- In dem Titel, "Custom-gleich - /hash" bedeutet "unterscheidet sich von den üblichen bereits deklarierte Funktionen". Dies bedeutet, dass ich bereits eine hash-Funktion, und ich es nicht ändern können.
- Hinzugefügt eine Antwort. Sie erkennen, dass Sie können entfernen Sie Felder aus dem hashcode, ohne zu brechen andere Nutzung, richtig? eine weniger spezifische hashcode ist immer noch eine gültige hashcode. beachten Sie auch, dass die Gleichstellung von hashcode bedeutet nichts in Bezug auf die Gleichstellung der eigentlichen Klasse Werte.
- Entfernen von Feldern aus
hashCode
allein verlassen, während Sie inequals
1. kann schlecht für die performance, 2. ist sicherlich eine richtige Maßnahme, 3. macht überhaupt keinen Sinn. Während @Hamal000 sagte nichts über seinen gleich, würde ich annehmen, dort enthalten sind auch da. - Erinnerung: stackoverflow.com/questions/27581/... und stackoverflow.com/questions/410236/...
Du musst angemeldet sein, um einen Kommentar abzugeben.
Können Sie einfach wickeln Sie Ihre
Request
Objekte inCachedRequest
Objekte, woCachedRequest
umsetzen würdenhashCode()
undequals()
basierend auf die gewünschten Felder, und Zugriff auf die eingebundenenRequest
.Ich bin mir ziemlich sicher, es ist nicht möglich, mit Guave. Es gibt einige legitime Fälle für die Verwendung einer benutzerdefinierten Äquivalenz, aber Sie sagen, Sie sind zu selten behandelt werden, indem die
CacheBuilder
undMapMaker
.1 Es gibt sogarcom.google.common.base.Equivalence
, aber es wird nur intern verwendet (siehe auch hier und hier).Müssen Sie machen Sie Ihre Schlüssel aus der Sie die gewünschten Felder für die Suche verwendet wird, oder wickeln Sie Ihre
Request
in einem anderen Objekt definierenequals
undhashCode
wie Sie wollen.1Der einzige Fall, in dem etwas vom Standard unterscheidet
equals
/hashCode
benutzt wird, ist mitweakKeys
(softKeys
existiert nicht mehr), und dann ist der==
/System.identityHashCode
combo. In keinem Fall können Sie die Gleichwertigkeit frei.Equivalence
ist öffentlich: docs.guava-libraries.googlecode.com/git/javadoc/com/google/...Maps.difference
).Wenn Sie nicht ändern können die hash-Funktion (ich verstehe immer noch nicht warum), dann brauchst du einen "wrapper" Schlüssel-cache, z.B.: