【发布时间】:2021-04-03 21:09:41
【问题描述】:
我有一张地图,它在调用Map.values() 时返回以下数据,它返回Collection<V>
[
Cache.CachedObject(inserted=1617483447407, value=Record(id=10, type=5, timestamp=2021-04-03T08:37:51.312Z)),
Cache.CachedObject(inserted=1617483446133, value=Record(id=11, type=6, timestamp=2021-04-03T08:37:51.312Z)),
Cache.CachedObject(inserted=1617483445030, value=Record(id=8, type=4, timestamp=2021-04-03T08:37:51.312Z))
]
如何从Collection<V> 返回List<Record>?
Cache类的代码如下
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//
package com.api.utils;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map.Entry;
public class Cache<K, V> {
private long timeToLive = 20000L;
private HashMap<K, V> cacheMap = new HashMap();
public Cache() {
if (this.timeToLive > 0L) {
Thread t = new Thread(() -> {
while(true) {
this.cleanup();
}
});
t.setDaemon(true);
t.start();
}
}
public void put(K key, V value) {
synchronized(this.cacheMap) {
this.cacheMap.put(key, new Cache.CachedObject(value));
}
}
public V get(K key) {
synchronized(this.cacheMap) {
Cache<K, V>.CachedObject c = (Cache.CachedObject)this.cacheMap.get(key);
return c == null ? null : c.value;
}
}
public void remove(K key) {
synchronized(this.cacheMap) {
this.cacheMap.remove(key);
}
}
public int size() {
synchronized(this.cacheMap) {
return this.cacheMap.size();
}
}
public void clear() {
synchronized(this.cacheMap) {
this.cacheMap.clear();
}
}
public Collection<V> values() {
synchronized(this.cacheMap) {
return this.cacheMap.values();
}
}
public void cleanup() {
long now = System.currentTimeMillis();
ArrayList deleteKey;
synchronized(this.cacheMap) {
Iterator<Entry<K, V>> itr = this.cacheMap.entrySet().iterator();
deleteKey = new ArrayList(this.cacheMap.size() / 2 + 1);
while(itr.hasNext()) {
Entry<K, V> entry = (Entry)itr.next();
K key = entry.getKey();
V cached = entry.getValue();
if (cached != null && now > ((Cache.CachedObject)cached).inserted + this.timeToLive) {
deleteKey.add(key);
}
}
}
for(Iterator var4 = deleteKey.iterator(); var4.hasNext(); Thread.yield()) {
K key = var4.next();
synchronized(this.cacheMap) {
this.cacheMap.remove(key);
}
}
}
public String toString() {
return "Cache(timeToLive=" + this.timeToLive + ", cacheMap=" + this.cacheMap + ")";
}
private class CachedObject {
public long inserted = System.currentTimeMillis();
public V value;
protected CachedObject(V value) {
this.value = value;
}
public String toString() {
return "Cache.CachedObject(inserted=" + this.getInserted() + ", value=" + this.getValue() + ")";
}
public long getInserted() {
return this.inserted;
}
public V getValue() {
return this.value;
}
}
}
【问题讨论】:
-
你能分享
Cache.CachedObject的来源吗? -
Cache的代码无法编译,错误很多,这肯定是XY problem,因为CachedObject没有被声明为泛型,内部map没有V类型对于它的值,但CachedObject<V>,并且必须更改它以使代码编译。大量的synchronized块应该替换为线程安全的映射,例如ConcurrentHashMap,或者至少通过应用Collections.synchronizedMap -
@AlexRudenko 不确定您遇到了什么错误。你在设计问题上是对的。这是库类之一,我现在实现了自己的。然而,给我同步块而不是一些线程安全集合的原因是缓存检索应该是恒定时间。不过,我对此毫无疑问。无论如何,非常感谢您将我推向正确的方向。
-
立即出现的错误:方法
Cache::put:incompatible types: Cache.CachedObject cannot be converted to V this.cacheMap.put(key, new Cache.CachedObject(value));方法Cache::cleanUp:error: incompatible types: Object cannot be converted to K K key = var4.next();
标签: java collections java-8 java-stream