Does Java 8 have cached support for suppliers?

后端 未结 3 1753
走了就别回头了
走了就别回头了 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:38

    The simplest solution would be

    public static  Supplier memoize(Supplier original) {
        ConcurrentHashMap store=new ConcurrentHashMap<>();
        return ()->store.computeIfAbsent("dummy", key->original.get());
    }
    

    However, the simplest is not always the most efficient.

    If you want a clean and efficient solution, resorting to an anonymous inner class to hold the mutable state will pay off:

    public static  Supplier memoize1(Supplier original) {
        return new Supplier() {
            Supplier delegate = this::firstTime;
            boolean initialized;
            public T get() {
                return delegate.get();
            }
            private synchronized T firstTime() {
                if(!initialized) {
                    T value=original.get();
                    delegate=() -> value;
                    initialized=true;
                }
                return delegate.get();
            }
        };
    }
    

    This uses a delegate supplier which will do the first time operation and afterwards, replace itself with a supplier that unconditionally returns the captured result of the first evaluation. Since it has final fields semantics, it can be unconditionally returned without any additional synchronization.

    Inside the synchronized method firstTime(), there is still an initialized flag needed because in case of concurrent access during initialization, multiple threads may wait at the method’s entry before the delegate has been replaced. Hence, these threads need to detect that the initialization has been done already. All subsequent accesses will read the new delegate supplier and get the value quickly.

提交回复
热议问题