Java8

2017-10-23 17 views
5

में लेज़ी अनुकरण मैं जावा में Lazy<T> अनुकरण करने के लिए निम्नलिखित कोड लिखा है:Java8

import java.util.function.Supplier; 

public class Main { 

    @FunctionalInterface 
    interface Lazy<T> extends Supplier<T> { 
     Supplier<T> init(); 
     public default T get() { return init().get(); } 
    } 

    static <U> Supplier<U> lazily(Lazy<U> lazy) { return lazy; } 
    static <T>Supplier<T> value(T value) { return()->value; } 

    private static Lazy<Thing> thing = lazily(()->thing=value(new Thing())); 
    public static void main(String[] args) { 

     System.out.println("One"); 
     Thing t = thing.get(); 
     System.out.println("Three"); 

    } 
    static class Thing{ Thing(){System.out.println("Two");}} 
} 

लेकिन मैं निम्नलिखित चेतावनी मिलती है:

"मुख्य में मूल्य (T) (com.company.Main.Thing) के लिए लागू नहीं किया जा सकता है कारण: प्रकार चर का कोई उदाहरण (रों) (रों) टी मौजूद ताकि Supplier<T> Lazy<Thing> "

के अनुरूप है

क्या आप कृपया मुझे यह जानने में मदद कर सकते हैं कि समस्या क्या है? अग्रिम धन्यवाद!

+1

[टेम्पलेट] का पालन करें (https://stackoverflow.com/a/29141814/2711488) * कड़ाई से * ... – Holger

उत्तर

1

value()Supplier देता है, जबकि thing फ़ील्ड में Lazy<Thing> है। आप Supplier को Lazy (जो भी parametrization के साथ) असाइन नहीं कर सकते हैं क्योंकि सभी Supplier उदाहरण Lazy उदाहरण नहीं हैं।

आगे, lazily() वापसी मूल्य (जो Supplier है) को thing पर असाइन करने की कोशिश की गई है, और यह उसी कारण से काम नहीं करेगा।

हम Lazy को lazily प्रकार बदल सकते हैं और है कि इनलाइन thing= काम (जो thing प्रारंभकर्ता अभिव्यक्ति के अंदर है) से हटा सकते हैं संकलन करने के लिए:

static <U> Lazy<U> lazily(Lazy<U> lazy) { return lazy; } 
static <T> Supplier<T> value(T value) { return()->value; } 

private static Lazy<Thing> thing = lazily(()->value(new Thing())); 

लेकिन मैं यकीन नहीं है कि क्या यह है कि तुम क्या करना चाहता था है प्राप्त।

तुम सिर्फ एक आलसी व्यवहार करना चाहता था, तो Supplier ही पहले से ही काम कर रहा है जब करने का अनुरोध किया है और जब एक Supplier बनाई गई है नहीं get() के रूप में आलसी केवल निष्पादित किया जाता है में सक्षम है।

आप एक कैशिंग तर्क चाहते हैं (केवल एक बार की गणना, और केवल गणना यह आवश्यक), तो आप कुछ इस तरह इस्तेमाल कर सकते हैं:

public class CachingSupplier<T> implements Supplier<T> { 
    private final Supplier<T> supplier; 
    private T cachedValue; 
    private boolean computed = false; 

    public CachingSupplier(Supplier<T> supplier) { 
     this.supplier = supplier; 
    } 

    public T get() { 
     if (!computed) { 
      cachedValue = supplier.get(); 
      computed = true; 
     } 
     return cachedValue; 
    } 
} 

आप गारंटी नहीं है कि supplier.get() एक बार अधिकतम पर बुलाया जाता है चाहते हैं, आप

if (!computed) { 
     synchronized (this) { 
      if (!computed) { 
       cachedValue = supplier.get(); 
       computed = true; 
      } 
     } 
    } 
    return cachedValue; 

यहाँ, एक double-checked locking प्रयोग किया जाता है: कुछ तुल्यकालन लागू हो सकते हैं।

4

LazySupplier का उप-वर्ग है और आप इसे अन्य तरीकों से डालने की कोशिश कर रहे हैं।

private static Lazy<Thing> thing = lazily(() -> thing = value(new Thing())); 

बदलने

को
private static Supplier<Thing> thing = lazily(() -> thing = value(new Thing())); 

काम करना चाहिए।

संबंधित मुद्दे