Java 中有哪些不同的记忆技术?

发布于 2024-09-16 14:42:01 字数 1435 浏览 6 评论 0 原文

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

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

发布评论

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

评论(3

煮茶煮酒煮时光 2024-09-23 14:42:01

要记住不带参数的函数,请使用 Guava 的 Suppliers.memoize(Supplier)。对于带参数的函数,请使用 < code>CacheBuilder.build(CacheLoader) 以参数值对象作为键。

To memoize functions without parameters, use Guava's Suppliers.memoize(Supplier). For functions with parameters, use CacheBuilder.build(CacheLoader) with parameter value objects as keys.

月野兔 2024-09-23 14:42:01

是的。使用 缓存 /google/guava" rel="noreferrer">番石榴。

例子:

import java.math.BigInteger;

import com.google.common.base.Preconditions;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;

public class Fibonacci {
    private static final LoadingCache<Integer, BigInteger> CACHE
            = CacheBuilder.newBuilder().build(CacheLoader.from(Fibonacci::fib));

    public static BigInteger fib(int n) {
        Preconditions.checkArgument(n >= 0);
        switch (n) {
        case 0:
            return BigInteger.ZERO;
        case 1:
            return BigInteger.ONE;
        default:
            return CACHE.getUnchecked(n - 1).add(CACHE.getUnchecked(n - 2));
        }
    }
}

Yes. Use caches from Guava.

Example:

import java.math.BigInteger;

import com.google.common.base.Preconditions;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;

public class Fibonacci {
    private static final LoadingCache<Integer, BigInteger> CACHE
            = CacheBuilder.newBuilder().build(CacheLoader.from(Fibonacci::fib));

    public static BigInteger fib(int n) {
        Preconditions.checkArgument(n >= 0);
        switch (n) {
        case 0:
            return BigInteger.ZERO;
        case 1:
            return BigInteger.ONE;
        default:
            return CACHE.getUnchecked(n - 1).add(CACHE.getUnchecked(n - 2));
        }
    }
}
提笔书几行 2024-09-23 14:42:01

使用简单的类型安全 Java 来记忆也很容易。

您可以使用以下可重用类从头开始执行此操作。

我将它们用作缓存,其寿命是网络应用程序上的请求。

当然,如果您需要驱逐策略或同步等更多功能,请使用 Guava MapMaker

如果您需要记住具有许多参数的方法,只需将参数放入使用这两种技术的列表中,然后将该列表作为单个参数传递即可。

abstract public class Memoize0<V> {
    //the memory
    private V value;
    public V get() {
        if (value == null) {
            value = calc();
        }
        return value;
    }
    /**
     * will implement the calculation that 
     * is to be remembered thanks to this class
     */
    public abstract V calc();
}

abstract public class Memoize1<P, V> {
    //The memory, it maps one calculation parameter to one calculation result
    private Map<P, V> values = new HashMap<P, V>();

    public V get(P p) {
        if (!values.containsKey(p)) {
            values.put(p, calc(p));
        }
        return values.get(p);
    }

    /**
     * Will implement the calculations that are
     * to be remembered thanks to this class
     * (one calculation per distinct parameter)
     */
    public abstract V calc(P p);
 }

这是这样使用的

    Memoize0<String> configProvider = new Memoize0<String>() {
        @Override
        public String calc() {
            return fetchConfigFromVerySlowDatabase();
        }
    };
    final String config = configProvider.get();

    Memoize1<Long, String> usernameProvider = new Memoize1<Long, String>() {
        @Override
        public String calc(Long id) {
            return fetchUsernameFromVerySlowDatabase(id);
        }
    };
    final String username = usernameProvider.get(123L);

Memoization is also easy with plain simple typesafe Java.

You can do it from scratch with the following reusable classes.

I use these as caches whose lifespan are the request on a webapp.

Of course use the Guava MapMaker if you need an eviction strategy or more features like synchronization.

If you need to memoize a method with many parameters, just put the parameters in a list with both techniques, and pass that list as the single parameter.

abstract public class Memoize0<V> {
    //the memory
    private V value;
    public V get() {
        if (value == null) {
            value = calc();
        }
        return value;
    }
    /**
     * will implement the calculation that 
     * is to be remembered thanks to this class
     */
    public abstract V calc();
}

abstract public class Memoize1<P, V> {
    //The memory, it maps one calculation parameter to one calculation result
    private Map<P, V> values = new HashMap<P, V>();

    public V get(P p) {
        if (!values.containsKey(p)) {
            values.put(p, calc(p));
        }
        return values.get(p);
    }

    /**
     * Will implement the calculations that are
     * to be remembered thanks to this class
     * (one calculation per distinct parameter)
     */
    public abstract V calc(P p);
 }

And this is used like this

    Memoize0<String> configProvider = new Memoize0<String>() {
        @Override
        public String calc() {
            return fetchConfigFromVerySlowDatabase();
        }
    };
    final String config = configProvider.get();

    Memoize1<Long, String> usernameProvider = new Memoize1<Long, String>() {
        @Override
        public String calc(Long id) {
            return fetchUsernameFromVerySlowDatabase(id);
        }
    };
    final String username = usernameProvider.get(123L);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文