8

私はポイントオブジェクトを持っています:

  class Point {
    final int x,y;
    ...
  }

これらのポイントは私のコードの至る所で使用/作成されるので、グアバキャッシュの使用を開始したいと思います。残念ながら、CacheLoaderは1つのパラメーターしか受け入れません。 ここでのstackoverflowに関する別の質問では、同様の問題にペアオブジェクトを使用します。しかし、キャッシュリクエストごとにダミーオブジェクトを作成するというアイデアは好きではありません。だから私は自分自身の回避策を考え出します:

オブジェクトはxとyで指定されているので、両方の値をlongにマージ(シフト)できると思います。これが私のキーになります。

void test(int x, int y) {
    Long key = (long) ((long) (x) << Integer.SIZE | y);
    Point point = cache.get(key);
}

CacheLoader<Long, Point> loader = new CacheLoader<Long, Point>() {
    public Point load(Long key) throws Exception {
    final int x,y;
        // shift magic
        x = (int) (key >> Integer.SIZE);
        y = key.intValue();
        return new Point(x, y);
    }
};

私は実際にはシフト初心者です。これは機能しますか?私は何か見落としてますか?これはペアクラスよりも「速い」ですか?それが私の質問です!

はい、私はコードをテストしました、そしてそれは私が言うことができる今のところうまくいきます。

4

2 に答える 2

9

これはどう?Point クラスは と を正しく実装する必要がequals()ありhashcode()ます。

static class Points {
  static final Interner<Point> INTERNER = Interners.newStrongInterner();

  public static Point cached(final int x, final int y) {
    return INTERNER.intern(new Point(x, y));
  }
}

あなたの実際の目的は、等しいオブジェクトをキャッシュすることでしたよね? これで十分です。使用法:

Point center = Points.cached(0, 0);

または、キャッシュの例を調整したバージョン:

CacheLoader<Point, Point> loader = new CacheLoader<Point, Point>() {
  @Override
  public Point load(final Point point) {
    return point;
  }
}
...
Point center = cache.get(new Point(0, 0));
于 2011-11-23T13:16:44.657 に答える
3

その方がおそらく高速ですが (違いが測定可能であれば)、ペア クラスを使用すると、コードの理解や再利用が大幅に改善されます。一般的な Pair クラスを使用します。

public final class Pair<L, R> {

    private final L left;
    private final R right;

    private Pair(L left, R right) {
        this.left = left;
        this.right = right;
    }

    public static <L,R>Pair<L,R> of(L left, R right){
        return new Pair<L, R>(left,right);
    }

    @Override
    public boolean equals(final Object obj) {
        if (obj instanceof Pair) {
            final Pair<?,?> other = (Pair<?,?>) obj;
            return Objects.equal(left,  other.left)
                && Objects.equal(right, other.right);
        } else {
            return false;
        }
    }

    @Override
    public int hashCode() {
        return Objects.hashCode(left, right);
    }

    @Override
    public String toString() {
        return MoreObjects.toStringHelper(this)
                      .add("left", left)
                      .add("right", right)
                      .toString();
    }

}

それをコードベースに組み込むと、複数の用途が見つかります。ビット シフトは実際には Java のようなものではありません (ただし、他の多くの人は同意しません)。

グアバのドキュメント

于 2011-11-23T11:27:29.270 に答える