18

私のコードには、メモ化を使用することが非常に理にかなっている (必須でさえあるように思える) いくつかの関数があります。

関数ごとに個別に手動で実装したくありません。何らかの方法がありますか (たとえば、 Python のように)、注釈を使用するか、他のことを行うことができるので、必要な関数でこれを自動的に取得できますか?

4

5 に答える 5

15

Spring 3.1 は、まさにこれを行う@Cacheableアノテーションを提供するようになりました。

名前が示すように、 @Cacheable は、キャッシュ可能なメソッド、つまり、結果がキャッシュに格納されるメソッドを区別するために使用されます。そのため、後続の呼び出し (同じ引数を使用) では、キャッシュ内の値が返されます。実際にメソッドを実行します。

于 2012-03-18T01:53:44.110 に答える
7

あなたが説明したように、アノテーションを使用して関数をメモ化しているように見えるTek271というメモ化ライブラリに出会いました。

于 2010-10-14T16:05:29.770 に答える
6

メモ化の言語ネイティブ実装はないと思います。

ただし、メソッドのデコレータとして簡単に実装できます。マップを維持する必要があります。マップのキーはパラメーターであり、値は結果です。

引数が 1 つのメソッドの簡単な実装を次に示します。

Map<Integer, Integer> memoizator = new HashMap<Integer, Integer>();

public Integer memoizedMethod(Integer param) {

    if (!memoizator.containsKey(param)) {
        memoizator.put(param, method(param));
    } 

    return memoizator.get(param);
}
于 2010-10-14T15:30:50.617 に答える
4

Google のguavaライブラリのFunctionインターフェイスを使用して、目的を簡単に達成できます。

import java.util.HashMap;
import java.util.Map;

import com.google.common.base.Function;

public class MemoizerTest {
  /**
   * Memoizer takes a function as input, and returns a memoized version of the same function.
   * 
   * @param <F>
   *          the input type of the function
   * @param <T>
   *          the output type of the function
   * @param inputFunction
   *          the input function to be memoized
   * @return the new memoized function
   */
  public static <F, T> Function<F, T> memoize(final Function<F, T> inputFunction) {
    return new Function<F, T>() {
      // Holds previous results
      Map<F, T> memoization = new HashMap<F, T>();

      @Override
      public T apply(final F input) {
        // Check for previous results
        if (!memoization.containsKey(input)) {
          // None exists, so compute and store a new one
          memoization.put(input, inputFunction.apply(input));
        }

        // At this point a result is guaranteed in the memoization
        return memoization.get(input);
      }
    };
  }

  public static void main(final String[] args) {
    // Define a function (i.e. inplement apply)
    final Function<Integer, Integer> add2 = new Function<Integer, Integer>() {
      @Override
      public Integer apply(final Integer input) {
        System.out.println("Adding 2 to: " + input);
        return input + 2;
      }
    };

    // Memoize the function
    final Function<Integer, Integer> memoizedAdd2 = MemoizerTest.memoize(add2);

    // Exercise the memoized function
    System.out.println(memoizedAdd2.apply(1));
    System.out.println(memoizedAdd2.apply(2));
    System.out.println(memoizedAdd2.apply(3));
    System.out.println(memoizedAdd2.apply(2));
    System.out.println(memoizedAdd2.apply(4));
    System.out.println(memoizedAdd2.apply(1));
  }
}

印刷する必要があります:

2 を追加: 1

3

2 を 2 に追加: 2

4

2 を 3 に追加

5

4

2 を追加: 4

6

3

2 回目に memoizedAdd2 が引数 2 と 1 に呼び出された (適用された) ことがわかります。適用の計算は実際には実行されず、格納された結果を取得しただけです。

于 2010-10-14T17:24:14.677 に答える