8

我有一个点对象:

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

因为这些点将在我的代码中到处使用/创建,所以我想开始使用番石榴缓存。不幸的是,CacheLoader 只接受一个参数。 stackoverflow 上的另一个问题使用 pair 对象来解决类似的问题。但我不喜欢为每个缓存请求创建一个虚拟对象的想法。所以我想出了自己的解决方法:

因为对象是由 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()and 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 类将使您的代码更好地理解或重用。我会选择一个通用的 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 回答