क्यों खाली स्ट्रीम के लिए Stream.allMatch () सही है?


84

मेरे सहयोगी और मेरे पास एक बग था जो हमारी धारणा के कारण था कि एक खाली स्ट्रीम कॉलिंग allMatch()वापस आ जाएगी false

if (myItems.allMatch(i -> i.isValid()) { 
    //do something
}

निश्चित रूप से, यह दस्तावेज़ीकरण मानने और न पढ़ने के लिए हमारी गलती की तरह है। लेकिन जो मुझे समझ में नहीं आता है वह यह है कि allMatch()खाली स्ट्रीम के लिए डिफ़ॉल्ट व्यवहार क्यों होता है true। इसका क्या कारण था? जैसे anyMatch()(जो विपरीत रूप से गलत रिटर्न करता है), इस ऑपरेशन का उपयोग अत्यावश्यक तरीके से किया जाता है जो मोनाड को छोड़ देता है और शायद एक ifबयान में उपयोग किया जाता है। उन तथ्यों को ध्यान में रखते हुए, क्या कोई कारण है कि अधिकांश उपयोग के लिए खाली स्ट्रीम पर allMatch()डिफ़ॉल्ट trueहोना वांछनीय है?


4
यह थोड़ा अजीब है। हम उम्मीद करेंगे कि अगर allMatchरिटर्न सही है तो ऐसा होना चाहिए anyMatch। इसके अतिरिक्त, खाली मामले के लिए, allMatch(...) == noneMatch(...)जो अजीब भी है।
रेडियोडेफ

6
विकिपीडिया का कहना है कि यह अधिवेशन है: en.wikipedia.org/wiki/Universal_quantification#The_empty_set
एलेक्स - GlassEditor.com

सिंटैक्स के बारे में बस एक त्वरित: अपने विधेय को लिखने के बजाय i -> i.isValid(), आप लिख सकते हैं Foo::isValid(जहां आप निश्चित रूप Fooसे जो भी कक्षा स्ट्रीमिंग कर रहे हैं, वह लिख सकते हैं)
मैटपुतनम

2
"इस ऑपरेशन का उपयोग एक अनिवार्य तरीके से किया जाता है जो मोनाड को विदा करता है" - मुझे इस कारक पर किसी भी निर्णय में संदेह है।
user253751

जवाबों:


115

इसे रिक्त सत्य के रूप में जाना जाता है । एक खाली संग्रह के सभी सदस्य आपकी स्थिति को संतुष्ट करते हैं; आखिरकार, क्या आप एक को इंगित कर सकते हैं जो नहीं करता है?

इसी तरह, anyMatchरिटर्न false, क्योंकि आप अपने संग्रह का एक तत्व नहीं पा सकते हैं जो स्थिति से मेल खाता है। यह बहुत से लोगों को भ्रमित कर रहा है, लेकिन यह खाली सेट के लिए "किसी भी" और "सभी" को परिभाषित करने का सबसे उपयोगी और सुसंगत तरीका है।


3
गीज़, मुझे बूलियन लॉजिक से नफरत है। मुझे लगता है कि आप जो कह रहे हैं उसका मुझे अंदाजा है। नकारात्मक की अनुपस्थिति एक सकारात्मक है, लेकिन सकारात्मकता की अनुपस्थिति नकारात्मक नहीं है।
tmn

13
@ThomasN। उसी तरह संख्याओं के एक खाली समूह के उत्पाद का मूल्य है, 1जबकि संख्याओं के एक खाली सेट का योग है 0। वे गुणन / जोड़ के लिए तटस्थ तत्व हैं। बूलियन्स के मामले में आपको लगता है कि है True and x = xऔर False or x = xइसलिए आप सामान्यीकरण करता है, तो andऔर orदृश्यों के लिए (कि क्या allऔर anyकर रहे हैं) आप के साथ खत्म हो Trueऔर Falseखाली मामले के लिए, यानी वे संबंधित तटस्थ तत्व।
बाकुरू

9
@ThomasN। anyMatchसकारात्मकता allMatchकी अनुपस्थिति के लिए परीक्षण , नकारात्मक की अनुपस्थिति के लिए परीक्षण।
user253751

3
ध्यान दें कि इस तरह से आप डी मॉर्गन के नियम की तरह अच्छे काम कर सकते हैं: stream.allMatch (विधेय) स्ट्रीम के समान ही है। धारा (टैन) (predicate.negate ())। इसी प्रकार, stream.allMatch (predicate.negate ()) stream.anyMatch (विधेय) के समान है।
हंस

1
@PatrickBard: आप कह सकते हैं "क्या आप किसी एक को इंगित कर सकते हैं", और यह पूरी तरह से मान्य है , लेकिन इसका मतलब यह है कि संग्रह के सभी सदस्य शर्त को पूरा करने में विफल होते हैं। संग्रह के सभी सदस्य शर्त को पूरा करते हैं, और संग्रह के सभी सदस्य शर्त को पूरा करने में विफल होते हैं। ये "यह गलत है कि संग्रह के सभी सदस्य शर्त को पूरा करते हैं" से अलग-अलग कथन हैं। जैसा मैंने कहा, यह भ्रामक है।
user2357112

10

यहाँ इस बारे में सोचने का एक और तरीका है:

allMatch()करने के लिए है &&कि क्या sum()करने के लिए है+

निम्नलिखित तार्किक कथनों पर विचार करें:

IntStream.of(1, 2).sum() + 3 == IntStream.of(1, 2, 3).sum()
IntStream.of(1).sum() + 2 == IntStream.of(1, 2).sum()

यह समझ में आता है क्योंकि sum()सिर्फ एक सामान्यीकरण है +। हालाँकि, जब आप एक और तत्व निकालते हैं तो क्या होता है?

IntStream.of().sum() + 1 == IntStream.of(1).sum()

हम देख सकते हैं कि यह IntStream.of().sum()एक विशेष तरीके से संख्याओं के खाली अनुक्रम को परिभाषित करने या योग करने के लिए समझ में आता है । यह हमें समन का "पहचान तत्व" या मूल्य देता है, जब किसी चीज़ में जोड़ा जाता है, तो कोई प्रभाव नहीं पड़ता है ( 0)।

हम उसी तर्क को Booleanबीजगणित पर लागू कर सकते हैं ।

Stream.of(true, true).allMatch(it -> it) == Stream.of(true).allMatch(it -> it) && true

अधिक उदारता से:

stream.concat(Stream.of(thing)).allMatch(it -> it) == stream.allMatch(it -> it) && thing

यदि stream = Stream.of()तब भी इस नियम को लागू करने की आवश्यकता है। हम इसे हल करने के लिए && के "पहचान तत्व" का उपयोग कर सकते हैं। true && thing == thing, तो Stream.of().allMatch(it -> it) == true


6

जब मैं list.allMatch(या अन्य भाषाओं में इसके एनालॉग्स) को कॉल करता हूं , तो मैं यह पता लगाना चाहता हूं कि क्या कोई आइटम listविधेय से मेल करने में विफल रहता है। यदि कोई आइटम नहीं हैं, तो कोई भी मिलान करने में विफल हो सकता है। मेरे निम्नलिखित तर्क वस्तुओं को चुन लेंगे और उनसे उम्मीद करेंगे कि वे विधेय से मेल खाएंगे। एक खाली सूची के लिए, मैं कोई आइटम नहीं चुनूंगा और तर्क अभी भी ध्वनि होगा।

क्या होगा अगर एक खाली सूची के लिए allMatchलौटे false?

मेरा सीधा तर्क विफल होगा:

 if (!myList.allMatch(predicate)) {
   throw new InvalidDataException("Some of the items failed to match!");
 }
 for (Item item : myList) { ... }

मुझे चेक को बदलने के लिए याद रखना होगा !myList.empty() && !myList.allMatch()

संक्षेप में, एक खाली सूची के लिए allMatchलौटना trueन केवल तार्किक रूप से ध्वनि है, यह निष्पादन के सुखद मार्ग पर भी है, कम जांच की आवश्यकता होती है।


आप शायद मतलबif (!allMatch)
assylias

3

ऐसा लग रहा है कि इसका आधार गणितीय प्रेरण है। कंप्यूटर विज्ञान के लिए इसका एक अनुप्रयोग एक पुनरावर्ती एल्गोरिदम का एक आधार मामला हो सकता है।

यदि धारा खाली है, तो परिमाणीकरण को रिक्त रूप से संतुष्ट कहा जाता है और हमेशा सच होता है। ओरेकल डॉक्स: स्ट्रीम ऑपरेशन और पाइपलाइन

यहां कुंजी यह है कि यह "रिक्त रूप से संतुष्ट" है, जो स्वभाव से, कुछ भ्रामक है। विकिपीडिया में इसके बारे में एक सभ्य चर्चा है।

शुद्ध गणित में, खाली तौर पर सही कथन आम तौर पर अपने आप में रुचि के नहीं होते हैं, लेकिन वे अक्सर गणितीय तर्क द्वारा प्रमाण के आधार मामले के रूप में उत्पन्न होते हैं। विकिपीडिया: खाली सच


1

जबकि इस सवाल का पहले ही कई बार सही उत्तर दिया जा चुका है, मैं एक और गणितीय दृष्टिकोण लाना चाहता हूं।

उसके लिए मैं एक धारा के रूप में एक सेट पर विचार करना चाहता हूं (गणितीय अर्थ में)। फिर

emptyStream.allMatch(x-> p(x))

यहां छवि विवरण दर्ज करेंजबकि से मेल खाती है

emtpyStream.anyMatch(x -> p(x))

से मेल खाती है यहां छवि विवरण दर्ज करें

यह दूसरा हिस्सा गलत है क्योंकि खाली सेट में कोई तत्व नहीं हैं। पहले वाला थोड़ा और मुश्किल है। आप इसे या तो परिभाषा के अनुसार सही मान सकते हैं या कुछ अन्य कारणों पर गौर कर सकते हैं कि ऐसा क्यों होना चाहिए।

इस अंतर को स्पष्ट करने के लिए एक उदाहरण है "मंगल ग्रह पर रहने वाले सभी मनुष्यों के 3 पैर होते हैं" (सत्य) और "मंगल पर 3 पैरों वाला एक मानव रहता है" (झूठा)

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.