Java:缓存计算结果的数据结构?

发布于 2024-08-07 04:55:37 字数 283 浏览 9 评论 0 原文

我有一个昂贵的计算,我想缓存其结果。有没有办法用两个键制作地图?我正在考虑类似 Map<(Thing1, Thing2), Integer> 的东西。

然后我可以检查:

if (! cache.contains(thing1, thing2)) {
  return computeResult();
}
else {
  return cache.getValue(thing1, thing2);
}

伪代码。但沿着这些思路。

I have an expensive computation, the result of which I'd like to cache. Is there some way to make a map with two keys? I'm thinking of something like Map<(Thing1, Thing2), Integer>.

Then I could check:

if (! cache.contains(thing1, thing2)) {
  return computeResult();
}
else {
  return cache.getValue(thing1, thing2);
}

pseudocode. But something along those lines.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

黑凤梨 2024-08-14 04:55:37

您需要创建一个包含 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。

You need to create a class that holds Thing1 and Thing2, e.g:

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() { ... };
 }

Then to use it:

Things key = new Things(thing1, thing2);
if (!cache.contains(key) {
    Integer result = computeResult();
    cache.put(key, result);
    return result;
} else {
    return cache.getValue(key);
}

Note you have to implement equals and hashcode to make this code work properly. If you need this code to be thread-safe then have a look at ConcurrentHashMap.

孤檠 2024-08-14 04:55:37

听起来你想要记忆。 Functional Java 的最新主干头具有记忆产品类型 P1对结果进行缓存的计算进行建模。

您可以这样使用它:

P1<Thing> myThing = new P1<Thing>() {
  public Thing _1() {
    return expensiveComputation();
  }
}.memo();

第一次调用 _1() 将运行昂贵的计算并将其存储在备忘录中。之后,将返回备忘录。

对于您的“两把钥匙”,您需要一个简单的配对类型。函数式 Java 也以类 P2 的形式提供了这一点。要记住这样的值,只需使用P1>

您还可以使用 Promise 类代替记忆。它已经在库中存在了一段时间,因此您只需要最新的二进制文件。您可以按如下方式使用它:

Promise<Thing> myThing =
  parModule(sequentialStrategy).promise(new P1<Thing>() {
    public Thing _1() {
      return expensiveComputation();
    }
  });

要获取结果,只需调用 myThing.claim()Promise 还提供了在结果上映射函数的方法,即使结果尚未准备好

您需要导入 static fj.control.parallel.ParModule.parModulefj.control.parallel.Strategy.sequentialStrategy。如果您希望计算在其自己的线程中运行,请将 sequentialStrategy 替换为 Strategy 类提供的其他策略之一。

Sounds like you want memoisation. The latest trunk head of Functional Java has a memoising product type P1 that models a computation whose result is cached.

You would use it like this:

P1<Thing> myThing = new P1<Thing>() {
  public Thing _1() {
    return expensiveComputation();
  }
}.memo();

Calling _1() the first time will run the expensive computation and store it in the memo. After that, the memo is returned instead.

For your "two keys", you'd want a simple pair type. Functional Java has this too in the form of the class P2<A, B>. To memoise such a value, simply use P1<P2<A, B>>.

You can also use the Promise<A> class instead of the memoisation. This has been in the library for a while, so you'd just need the latest binary. You would use that as follows:

Promise<Thing> myThing =
  parModule(sequentialStrategy).promise(new P1<Thing>() {
    public Thing _1() {
      return expensiveComputation();
    }
  });

To get the result out, simply call myThing.claim(). Promise<A> also provides methods for mapping functions over the result even if the result is not yet ready.

You need to import static fj.control.parallel.ParModule.parModule and fj.control.parallel.Strategy.sequentialStrategy. If you want the computation to run in its own thread, replace sequentialStrategy with one of the other strategies provided by the Strategy class.

寄居者 2024-08-14 04:55:37

如果您使用 Google 收藏集,则其MapMaker 类有一个 makeComputingMap 方法完全按照您的描述进行操作。作为免费的奖励,它也是线程安全的(实现 ConcurrentMap)。

至于两个键的事情,您必须创建一个包含两个键的类,并实现 equalshashCode 和(如果适用)的合适实现compareTo 按照您想要的方式进行关键比较。

If you use Google Collections, its MapMaker class has a makeComputingMap method that does exactly what you described. As a free bonus, it's also thread-safe (implements ConcurrentMap).

As for the two-keys thing, you will have to make a class that contains the two keys, and implement a suitable implementation of equals, hashCode, and (if applicable) compareTo that does the key comparison the way you want it.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文