Does Java 8 have cached support for suppliers?

后端 未结 3 1734
走了就别回头了
走了就别回头了 2020-12-29 02:52

The guava library has it\'s own Supplier which does not extend Java 8 Supplier. Also guava provides a cache for suppliers - Suppliers#memoize.

Is there something sim

3条回答
  •  被撕碎了的回忆
    2020-12-29 03:41

    There's no built-in Java function for memoization, though it's not very hard to implement it, for example, like this:

    public static  Supplier memoize(Supplier delegate) {
        AtomicReference value = new AtomicReference<>();
        return () -> {
            T val = value.get();
            if (val == null) {
                val = value.updateAndGet(cur -> cur == null ? 
                        Objects.requireNonNull(delegate.get()) : cur);
            }
            return val;
        };
    }
    

    Note that different implementation approaches exist. The above implementation may call the delegate several times if the memoized supplier requested simultaneously several times from the different threads. Sometimes such implementation is preferred over the explicit synchronization with lock. If lock is preferred, then DCL could be used:

    public static  Supplier memoizeLock(Supplier delegate) {
        AtomicReference value = new AtomicReference<>();
        return () -> {
            T val = value.get();
            if (val == null) {
                synchronized(value) {
                    val = value.get();
                    if (val == null) {
                        val = Objects.requireNonNull(delegate.get());
                        value.set(val);
                    }
                }
            }
            return val;
        };
    }
    

    Also note, as @LouisWasserman correctly mentioned in comments, you can easily transform JDK supplier into Guava supplier and vice versa using method reference:

    java.util.function.Supplier jdkSupplier = () -> "test";
    com.google.common.base.Supplier guavaSupplier = jdkSupplier::get;
    java.util.function.Supplier jdkSupplierBack = guavaSupplier::get;
    

    So it's not a big problem to switch between Guava and JDK functions.

提交回复
热议问题