我有一個昂貴的計算,我想要緩存的結果。有兩種方法可以製作地圖嗎?我在想像Map<(Thing1, Thing2), Integer>
。Java:緩存計算結果的數據結構?
然後我可以檢查:
if (! cache.contains(thing1, thing2)) {
return computeResult();
}
else {
return cache.getValue(thing1, thing2);
}
僞代碼。但是沿着這些線。
我有一個昂貴的計算,我想要緩存的結果。有兩種方法可以製作地圖嗎?我在想像Map<(Thing1, Thing2), Integer>
。Java:緩存計算結果的數據結構?
然後我可以檢查:
if (! cache.contains(thing1, thing2)) {
return computeResult();
}
else {
return cache.getValue(thing1, thing2);
}
僞代碼。但是沿着這些線。
你需要創建一個保存Thing1和Thing2,一類如:
class Things {
public final Thing1 thing1;
public final Thing2 thing2;
public Things(Thing1 thing1, Thing2 thing2) {
this.thing1 = thing1;
this.thing2 = thing2;
}
@Override
public boolean equals(Object obj) { ... }
@Override
public int hashCode() { ... };
}
然後使用它:
Things key = new Things(thing1, thing2);
if (!cache.contains(key) {
Integer result = computeResult();
cache.put(key, result);
return result;
} else {
return cache.getValue(key);
}
注意,你必須實現equals和hashCode,以使此代碼工作正常。如果您需要此代碼以保證線程安全,請查看ConcurrentHashMap。
如果您使用Google Collections,其MapMaker
類有一個makeComputingMap
方法,完全按照您所描述的方法。作爲免費獎勵,它也是線程安全的(實施ConcurrentMap
)。
至於兩鍵的事情,你將不得不作出一個包含這兩個鍵的一類,並實施適當的實施equals
,hashCode
,以及(如適用)compareTo
,做的鍵比較你所希望的方式它。
我都是Google集合,但我很難理解這是如何工作的。 – 2009-10-12 02:42:17
您基本上創建一個調用您的'computeResult'函數的'Function'對象。當您從地圖中獲取相應的項目時,Google對象將負責調用該函數並緩存其值。 :-) – 2009-10-12 02:57:14
聽起來像你想memoisation。 Functional Java的最新樹幹頭具有memmoising產品類型P1
,該模型對結果進行高速緩存的計算進行建模。
你會使用這樣的:
P1<Thing> myThing = new P1<Thing>() {
public Thing _1() {
return expensiveComputation();
}
}.memo();
調用_1()第一次將運行昂貴的計算,並將其存儲在備忘錄。之後,備忘錄將被返回。
對於你的「兩把鑰匙」,你想要一個簡單的配對類型。 Functional Java也有類P2<A, B>
的形式。要記住這樣的值,只需使用P1<P2<A, B>>
即可。
您也可以使用Promise<A>
類代替memoisation。這已經在圖書館一段時間了,所以你只需要最新的二進制文件。您可以使用如下:
Promise<Thing> myThing =
parModule(sequentialStrategy).promise(new P1<Thing>() {
public Thing _1() {
return expensiveComputation();
}
});
要獲得結果,只需撥打myThing.claim()
即可。 Promise<A>
也提供了在結果上映射函數的方法,即使結果還沒有準備好。您需要import static fj.control.parallel.ParModule.parModule
和fj.control.parallel.Strategy.sequentialStrategy
。如果您希望計算在其自己的線程中運行,請將sequentialStrategy
替換爲Strategy
類提供的其他策略之一。
Eerie ..我*只是*在五分鐘前做了這個,然後來到了所以看到這個問題......我推薦這個實現hashCode方法(這只是默認的eclipse實現):'return (31+ thing1.hashCode())* 31 + thing2.hashCode();' – Kip 2009-10-12 02:31:13
@Kip:其實,我推薦使用Apache Commons Lang中的'HashCodeBuilder','EqualsBuilder'和'CompareToBuilder'。 :-) – 2009-10-12 02:34:53
我花了不到10分鐘來實現這一點,現在我的程序在25%的時間內運行。哇。 – 2009-10-12 02:51:21