سؤال

لدي حساب باهظ الثمن ، والنتيجة التي أرغب في ذاكرة التخزين المؤقت. هل هناك طريقة لإنشاء خريطة مع مفتاحين؟ أفكر في شيء مثل Map<(Thing1, Thing2), Integer>.

ثم يمكنني التحقق:

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

كود مزيف. لكن شيء على طول تلك الخطوط.

هل كانت مفيدة؟

المحلول

تحتاج إلى إنشاء فصل يحمل الشيء 1 و 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);
}

لاحظ أنه يتعين عليك تنفيذ متساوٍ ورمز التجزئة لجعل هذا الرمز يعمل بشكل صحيح. إذا كنت بحاجة إلى أن يكون هذا الرمز آمنًا لخيط الخيط ، فاحرص على إلقاء نظرة على ConcurrentHashMap.

نصائح أخرى

يبدو أنك تريد المذكرات. أحدث رأس صندوق جافا الوظيفية لديه نوع منتج مذكرات P1 هذا النماذج حساب الذي تم تخزينه مؤقتًا.

سوف تستخدمه مثل هذا:

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

استدعاء _1 () أول مرة ستقوم تشغيل الحساب باهظ الثمن وتخزينه في المذكرة. بعد ذلك ، يتم إرجاع المذكرة بدلاً من ذلك.

بالنسبة إلى "مفتاحين" ، تريد نوع زوج بسيط. Java الوظيفية لديها هذا أيضا في شكل الفصل P2<A, B>. لمذكرات مثل هذه القيمة ، ببساطة استخدم P1<P2<A, B>>.

يمكنك أيضا استخدام Promise<A> الفصل بدلا من المذكرة. لقد كان هذا في المكتبة لفترة من الوقت ، لذلك ستحتاج فقط إلى أحدث ثنائي. يمكنك استخدام ذلك على النحو التالي:

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 صف دراسي.

إذا كنت تستخدم مجموعات جوجل, ، إنه MapMaker الفصل لديه makeComputingMap الطريقة التي تفعل بالضبط ما وصفته. كمكافأة مجانية ، إنها أيضًا آمنة من الخيوط (تنفذ ConcurrentMap).

أما بالنسبة للشيء المتوحشين ، فسيتعين عليك إنشاء فصل يحتوي على مفتاحين ، وتنفيذ تنفيذ مناسب لـ equals, hashCode, و (إن أمكن) compareTo هذا يفعل المقارنة الرئيسية بالطريقة التي تريدها.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top