2016-02-28 4 views
20

जावा 8 Stream एपीआई डिजाइन की समीक्षा, मैं Stream.reduce() तर्क पर सामान्य निश्चरता से आश्चर्यचकित था:Stream.reduce() जैसे API में invariance चुनने के अच्छे कारण क्या हैं?

<U> U reduce(U identity, 
      BiFunction<U,? super T,U> accumulator, 
      BinaryOperator<U> combiner) 

ही एपीआई का एक उचित रूप में अधिक बहुमुखी संस्करण U को सहप्रसरण/व्यक्तिगत संदर्भों पर contravariance आवेदन किया है हो सकता है, इस तरह के के रूप में:

// Assuming we want to reuse these tools all over the place: 
BiFunction<Number, Number, Double> numberAdder = 
    (t, u) -> t.doubleValue() + u.doubleValue(); 

// This currently doesn't work, but would work with the suggestion 
Stream<Number> stream = Stream.of(1, 2L, 3.0); 
double sum = stream.reduce(0.0, numberAdder, numberAdder); 
:

<U> U reduce(U identity, 
      BiFunction<? super U, ? super T, ? extends U> accumulator, 
      BiFunction<? super U, ? super U, ? extends U> combiner) 

इस के बाद, जो संभव नहीं है, वर्तमान में के लिए अनुमति होगी

वर्कअराउंड, उपयोग विधि संदर्भ "मजबूर" करने के लिए लक्ष्य प्रकार में प्रकार:

double sum = stream.reduce(0.0, numberAdder::apply, numberAdder::apply); 

सी # इस विशेष समस्या नहीं है, के रूप में Func(T1, T2, TResult) इस प्रकार परिभाषित किया गया है, घोषणा-साइट विचरण का उपयोग कर, जिसका अर्थ है सुझाव डिजाइन पर मौजूदा डिजाइन के

public delegate TResult Func<in T1, in T2, out TResult>(
    T1 arg1, 
    T2 arg2 
) 

क्या फायदे हैं (और संभवतः, ईजी निर्णय के लिए कारणों): Func उपयोग कर किसी भी एपीआई मुक्त करने के लिए इस व्यवहार हो जाता है?

या, अलग-अलग पूछा गया कि मैं सुझाए गए डिज़ाइन की चेतावनी क्या कर सकता हूं (उदाहरण के लिए अनुमान की कठिनाइयों, समांतरता बाधाएं, या कमीशन ऑपरेशन जैसे विशिष्टता जैसे विशिष्टता, भविष्य की जावा की घोषणा की प्रत्याशा- BiFunction<in T, in U, out R> पर साइट भिन्नता, ...)?

+2

मैं जवाब देता है संदिग्ध वहाँ टाइप अनुमान को कठिन esp बना देगा क्योंकि मुझे संदेह है कि यह स्पष्ट होने के बिना कुछ प्रकार के अनावश्यक छोड़ देगा (टाइप अनुमान के बिंदु को हराकर) –

+1

@ पीटर लेवरी: यह मेरी चिंता भी थी, लेकिन 1) क्या आप इसे साबित कर सकते हैं? :) 2) स्कैला जानता है 'ट्रैवर्सएबलऑन.ड्यूज [ए 1>: ए] (सेशन: (ए 1, ए 1) ⇒ ए 1): ए 1' –

+0

एक तरीका इस तरह एक एपीआई लिखना होगा और देखें कि जब आप उपयोग करने का प्रयास करते हैं तो क्या होता है यह। –

उत्तर

5

लैम्ब्डा विकास के इतिहास के माध्यम से रेंगने और अलग है इस निर्णय के लिए "" कारण मुश्किल है - अंततः, किसी को इस प्रश्न का उत्तर देने के लिए डेवलपर्स में से एक के लिए इंतजार करना होगा।

  • धारा इंटरफेस कई पुनरावृत्तियों और refactorings आया है:

    कुछ संकेत निम्नलिखित हो सकता है।Stream इंटरफ़ेस के शुरुआती संस्करणों में से एक में, reduce विधियों को समर्पित किया गया है, और प्रश्न में reduce विधि के सबसे नज़दीक वाले को अभी भी Stream#fold कहा जाता है। combiner पैरामीटर के रूप में इसे पहले से ही BinaryOperator प्राप्त हुआ है।

  • दिलचस्प बात यह है कि, थोड़ी देर के लिए, लैम्ब्डा प्रस्ताव में एक समर्पित इंटरफ़ेस Combiner<T,U,R> शामिल था। Counterintuitively, यह Stream#reduce समारोह में combiner के रूप में उपयोग नहीं किया गया था। इसके बजाए, इसे reducer के रूप में उपयोग किया गया था, जो आजकल accumulator के रूप में जाना जाता है। हालांकि, Combiner इंटरफ़ेस replaced with BiFunction in a later revision था।

  • यहां प्रश्न का सबसे हड़ताली समानता thread about the Stream#flatMap signature at the mailing list में पाई जाती है, जिसे स्ट्रीम विधि हस्ताक्षर के भिन्नताओं के बारे में सामान्य प्रश्न में बदल दिया जाता है।

    <R> Stream<R> flatMap(Function<? super T, ? extends Stream<? extends R>> mapper);

    बजाय

    :: वे, उदाहरण के

    के लिए ब्रायन मुझे सही करने के रूप में कुछ स्थानों में इन तय

    <R> Stream<R> flatMap(Function<T, Stream<? extends R>> mapper);

    लेकिन गौर किया है कि कुछ स्थानों में, यह संभव नहीं था:

    T reduce(T identity, BinaryOperator<T> accumulator);

    और

    Optional<T> reduce(BinaryOperator<T> accumulator);

    तय नहीं किया जा सकता है, क्योंकि वे 'BinaryOperator' का इस्तेमाल किया, लेकिन अगर 'BiFunction' प्रयोग किया जाता है तो हम और अधिक लचीलापन

    <U> U reduce(U identity, BiFunction<? super U, ? super T, ? extends U> accumulator, BinaryOperator<U> combiner)

    बजाय:

    <U> U reduce(U identity, BiFunction<U, ? super T, U> accumulator, BinaryOperator<U> combiner);

    ही (मेरे द्वारा जोर) 'BinaryOperator'

    के बारे में टिप्पणी।


केवल औचित्य है कि मैं नहीं एक BiFunction साथ BinaryOperator की जगह के लिए मिला अंततः response to this statement, in the same thread में दिया गया था:

BinaryOperator BiFunction द्वारा भले ही बदला नहीं जाएगा, के रूप में आपने कहा, यह अधिक लचीलापन पेश करता है, एक बाइनरीऑपरेटर पूछता है कि दो पैरामीटर और रिटर्न प्रकार समान है, इसलिए इसमें अवधारणात्मक रूप से अधिक वजन है (ईजी पहले से ही वोट देता है)।

हो सकता है कि किसी को है कि यह निर्णय शासित विशेषज्ञ समूह की मतदान के एक perticular संदर्भ की खुदाई कर सकते हैं, लेकिन शायद इस उद्धरण पहले से ही पर्याप्त कारण है कि यह जिस तरह से यह है के सवाल ...

+0

पर जाएं, अपने पुरातत्व के लिए धन्यवाद। यह स्थिति को समझाता है, भले ही मैं थोड़ा निराश हूं :) –

1

मेरी राय में यह प्रस्तावित है कि प्रस्तावित वृद्धि के लिए कोई वास्तविक उपयोग केस नहीं है। प्रस्तावित जावाडोक में 3 और प्रकार के पैरामीटर और 5 और वाइल्डकार्ड हैं। मुझे लगता है कि पूरी चीज आधिकारिक एपीआई को सरल बनाने के लिए पर्याप्त है क्योंकि नियमित जावा डेवलपर्स कंपाइलर को खुश करने की कोशिश कर रहे अपने दिमाग को खोने के लिए (अक्सर सक्षम नहीं हैं) चाहते हैं। बस रिकॉर्ड के लिए, आपके reduce() में केवल टाइप हस्ताक्षर में 165 वर्ण हैं।

इसके अलावा, .reduce() तर्क अक्सर लैम्ब्डा भाव के रूप में आपूर्ति की जाती है, तो अधिक बहुमुखी संस्करण होने में कोई वास्तविक मतलब नहीं है ऐसे भाव अक्सर नहीं या बहुत सरल व्यापार तर्क होते हैं और इसलिए केवल एक बार उपयोग किया जाता है जब।

उदाहरण के लिए मैं एक जिज्ञासु जावा डेवलपर कि जेनरिक पहेली प्यार करता है अपने शानदार jOOQ पुस्तकालय का एक उपयोगकर्ता और भी हूँ, लेकिन अक्सर मैं एसक्यूएल tuples की सादगी याद आती है मैं वजह से मेरे अपने इंटरफेस में वाइल्डकार्ड डाल करने के लिए जब टाइप Result<T> में पैरामीटर और मुसीबतों का प्रकार उत्पन्न जब रिकॉर्ड प्रकारों की इंटरफेस के साथ काम - नहीं है कि यह एक jOOQ गलती

+0

* "क्योंकि नियमित जावा डेवलपर्स नहीं चाहते हैं (अक्सर सक्षम नहीं हैं) अपने दिमाग को खोने की कोशिश कर रहे हैं कंपाइलर को खुश करें "* - सुझाव पढ़ने के लिए कठिन होगा, हां, लेकिन यह उपयोगकर्ताओं को" कंपाइलर को खुश करने "के लिए आसान बनाता है। यही वह जगह है जहां भिन्नता 0 उपयोगी हो सकती है –

+1

यदि आपको असली उपयोग केस मिल गया है तो शायद इसे मूल प्रश्न में पोस्ट करने लायक है! मैंने एक को समझने की कोशिश की लेकिन – Raffaele

+1

मुझे ऐसा नहीं लगता कि यह सवाल बिल्कुल सही है - अगर आपका दावा यह है कि यह जोड़ा नहीं गया है क्योंकि इसमें कोई दिलचस्पी नहीं है तो कृपया एपीआई चर्चाओं से सबूत के साथ इसे वापस लें । –

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