स्ट्रीम का उपयोग करके इस लूप को फिर से लिखने के बारे में कोई कैसे जाता है।

private final List<RegionSpecificValidator> validators;
public Item applyValidations(Item inbound, Holder holder, Product product) {
    Item toValidate = inbound;
    for (var validator: validators)
        toValidate = validator.validate(toValidate, holder, product);
    return toValidate;
}

validators.stream().reduce(...) का उपयोग करके इस लूप को फिर से लिखना संभव होना चाहिए

मैंने यहां मार्गदर्शन का उपयोग करने का प्रयास किया है, लेकिन मैं यह नहीं समझ सकता कि BiFunction इंटरफ़ेस को किस प्रकार कार्यान्वित करने की आवश्यकता है और कैसे।
इंटरफ़ेस जैसा कि यह वर्तमान में खड़ा है, इस तरह दिखता है:

public interface RegionSpecificValidator {
    Item validate(Item toValidate, Holder holder, Product product);
}

मैंने इस मार्गदर्शन को देखा है: /a>
हालांकि यह स्पष्ट नहीं है कि मैं इस मामले में andThen कैसे कार्यान्वित करता हूं, या यहां तक ​​कि यदि यह संभव है।

1
Jim 7 जिंदा 2022, 11:26
1
सफलता/विफलता के मामले में विशिष्ट सत्यापनकर्ता क्या लौटाते हैं?
 – 
Slimu
7 जिंदा 2022, 11:44

2 जवाब

सबसे बढ़िया उत्तर

आपको ट्रांसफॉर्मर और कॉम्बिनर के साथ कम () विधि

तीन तर्क इस प्रकार हैं:

  • inbound बेस केस है। उदाहरण के लिए, यदि validators एक खाली सूची है, तो यह वह वस्तु है जो डिफ़ॉल्ट रूप से वापस आती है
  • (toValidate, validator) -> validator.validate(toValidate, holder, product) यह एक Item और एक validator लेता है और एक Item बनाता है। यह सत्यापनकर्ता पर validate() विधि के माध्यम से होता है।
  • (prev, next) -> next परिभाषित करता है कि दो वस्तुओं के बीच कमी कैसे होनी चाहिए - आपको एक को चुनना होगा। आपके for-लूप में आप हमेशा toValidate को नए मान के साथ ओवरराइट कर रहे हैं, इसलिए इस मामले में हमें next, यानी अंतिम तत्व जो हमने validator.validate() से प्राप्त किया है, को वापस करना चाहिए।
public Item applyValidations(Item inbound, Holder holder, Product product) {
    return validators.stream().reduce(
        inbound, 
        (toValidate, validator) -> validator.validate(toValidate, holder, product), 
        (prev, next) -> next
    );
}
2
Stefan Zhelyazkov 7 जिंदा 2022, 11:49
1
आप किंवदंती, विश्वास नहीं कर सकते कि यह इतना आसान था, पूरी सुबह मेरा सिर थपथपाता रहा, केवल यह खोजने के लिए कि यह इतना आसान है। धन्यवाद!
 – 
Jim
7 जिंदा 2022, 11:59
मैं फिर से सोचूंगा यदि यह for लूप की तुलना में अधिक उचित कोड है, हालांकि आईएमओ अधिक पठनीय है।
 – 
daniu
7 जिंदा 2022, 12:06

आप कुछ इस तरह का उपयोग करके अपने सभी सत्यापनकर्ताओं को एक ही में कम कर सकते हैं:

RegionSpecificValidator validator = validators.stream().reduce(
    (i, h, p) -> i,
    (a, b) -> (i, h, p) -> b.validate(a.validate(i, h, p), h, p)
);
  • (i, h, p) -> i: प्रारंभिक सत्यापनकर्ता, केवल इनपुट आइटम लौटाता है। आवश्यकता है, क्योंकि एकल पैरामीटर reduce() विधि एक Optional लौटाती है और हम इसे यहां नहीं चाहते हैं।
  • (a, b) -> (i, h, p) -> b.validate(a.validate(i, h, p), h, p): जब लिखा जाता है, तो इसका अधिक अर्थ हो सकता है:
    (a, b) -> {// `a` और `b` दोनों सत्यापनकर्ता हैं      वापसी (i, h, p) -> {// सत्यापनकर्ता इंटरफ़ेस का एक नया कार्यान्वयन बनाएं          i = a.Validate(i, h, p);  // `ए` से परिणाम सहेजा जाएगा          वापसी बी। मान्य करें (आर, एच, पी);  // और फिर `बी` . के पास गया      }  }    यह कोड दो सत्यापनकर्ताओं को एक साथ "विलय" करता है, पहले पैरामीटर को लागू करता है, और फिर उस लौटा Item का उपयोग अगले सत्यापनकर्ता को पारित करने के लिए तर्क के रूप में करता है।  इन दोनों को फिर RegionSpecificValidator प्रकार के लैम्ब्डा में लपेटा जाता है।  ध्यान दें कि यह केवल तभी काम करेगा जब RegionSpecificValidator एक कार्यात्मक इंटरफ़ेस हो।  (interface में एक और केवल एक abstract विधि)

यह भी केवल एक बार किया जा सकता है (iff validators अपरिवर्तनीय है और कक्षा के निर्माण समय पर दिया गया है):

private final RegionSpecificValidator validator;

public YourClass(List<Validator> validators) {
    this.valdiator = validators.stream().reduce(
        (i, h, p) -> i,
        (a, b) -> (i, h, p) -> b.validate(a.validate(i, h, p), h, p)
    );
}

public Item applyValidations(Item inbound, Holder holder, Product product) {
    return validator.validate(inbound, holder, product);
}
0
Lino 7 जिंदा 2022, 12:04