Java Language
ऐच्छिक
खोज…
परिचय
Optional
एक कंटेनर ऑब्जेक्ट है जिसमें एक गैर-शून्य मान हो सकता है या नहीं हो सकता है। यदि कोई मान मौजूद है, तो isPresent()
true
लौटेगा और get()
मान लौटाएगा।
अतिरिक्त तरीके जो निहित मूल्य की उपस्थिति पर निर्भर करते हैं, जैसे कि orElse()
, जो कि मान मौजूद नहीं होने पर एक डिफ़ॉल्ट मान लौटाता है, और ifPresent()
जो कोड का एक खंड निष्पादित करता है यदि मान मौजूद है।
वाक्य - विन्यास
- Optional.empty () // एक खाली वैकल्पिक उदाहरण बनाता है।
- Optional.of (मान) // निर्दिष्ट गैर-शून्य मान के साथ एक वैकल्पिक देता है। पारित मूल्य शून्य होने पर NullPointerException को फेंक दिया जाएगा।
- Optional.ofNullable (value) // निर्दिष्ट मान के साथ एक वैकल्पिक देता है जो शून्य हो सकता है।
वैकल्पिक खाली होने पर डिफ़ॉल्ट मान लौटाएं
सिर्फ Optional.get()
उपयोग न करें Optional.get()
क्योंकि NoSuchElementException
को फेंक सकता है। Optional.orElse(T)
और Optional.orElseGet(Supplier<? extends T>)
विधियाँ वैकल्पिक होने पर डिफ़ॉल्ट मान प्रदान करने का एक तरीका प्रदान करती हैं।
String value = "something";
return Optional.ofNullable(value).orElse("defaultValue");
// returns "something"
return Optional.ofNullable(value).orElseGet(() -> getDefaultValue());
// returns "something" (never calls the getDefaultValue() method)
String value = null;
return Optional.ofNullable(value).orElse("defaultValue");
// returns "defaultValue"
return Optional.ofNullable(value).orElseGet(() -> getDefaultValue());
// calls getDefaultValue() and returns its results
orElse
और orElseGet
बीच महत्वपूर्ण अंतर यह है कि उत्तरार्द्ध का मूल्यांकन केवल तब किया जाता है जब वैकल्पिक खाली होता है, जबकि पूर्व में दिए गए तर्क का मूल्यांकन किया जाता है, भले ही वैकल्पिक खाली न हो। इसलिए orElse
उपयोग केवल स्थिरांक के लिए किया जाना चाहिए और किसी भी प्रकार की गणना के आधार पर मूल्य की आपूर्ति के लिए नहीं होना चाहिए।
नक्शा
का प्रयोग करें map()
की विधि Optional
मानों हो सकता है के साथ काम करने के लिए null
स्पष्ट कर बिना null
चेक:
(ध्यान दें कि map()
और filter()
संचालन का मूल्यांकन तुरंत किया जाता है, उनके स्ट्रीम समकक्षों के विपरीत जिनका केवल एक टर्मिनल ऑपरेशन के लिए मूल्यांकन किया जाता है।)
वाक्य - विन्यास:
public <U> Optional<U> map(Function<? super T,? extends U> mapper)
कोड उदाहरण:
String value = null;
return Optional.ofNullable(value).map(String::toUpperCase).orElse("NONE");
// returns "NONE"
String value = "something";
return Optional.ofNullable(value).map(String::toUpperCase).orElse("NONE");
// returns "SOMETHING"
क्योंकि Optional.map () एक खाली वैकल्पिक रिटर्न देता है जब इसकी मैपिंग फ़ंक्शन शून्य हो जाती है, तो आप कई मैप्स () संचालनों को अशक्त-सुरक्षित डेरेफेरिंग के रूप में चेन कर सकते हैं। इसे नल-सुरक्षित चेनिंग के रूप में भी जाना जाता है।
निम्नलिखित उदाहरण पर विचार करें:
String value = foo.getBar().getBaz().toString();
getBar
, getBaz
और toString
भी संभवतः NullPointerException
फेंक सकता है।
यहां Optional
का उपयोग करके toString()
से मूल्य प्राप्त करने का एक वैकल्पिक तरीका है:
String value = Optional.ofNullable(foo)
.map(Foo::getBar)
.map(Bar::getBaz)
.map(Baz::toString)
.orElse("");
यदि मैपिंग फ़ंक्शन में से कोई भी रिक्त हो, तो यह एक रिक्त स्ट्रिंग लौटाएगा।
नीचे एक और उदाहरण है, लेकिन थोड़ा अलग है। यह मूल्य तभी प्रिंट करेगा जब कोई भी मैपिंग फ़ंक्शन शून्य नहीं लौटा।
Optional.ofNullable(foo)
.map(Foo::getBar)
.map(Bar::getBaz)
.map(Baz::toString)
.ifPresent(System.out::println);
यदि कोई मूल्य नहीं है, तो एक अपवाद फेंक दें
निहित मान प्राप्त करने या अपवाद सेट न करने के लिए Optional
के orElseThrow()
विधि का उपयोग करें, अगर यह सेट नहीं किया गया है। यह कॉलिंग get()
समान है, सिवाय इसके कि यह मनमाना अपवाद प्रकारों के लिए अनुमति देता है। विधि एक आपूर्तिकर्ता को ले जाती है जिसे फेंक दिए जाने वाले अपवाद को वापस करना होगा।
पहले उदाहरण में, विधि केवल निहित मूल्य लौटाती है:
Optional optional = Optional.of("something");
return optional.orElseThrow(IllegalArgumentException::new);
// returns "something" string
दूसरे उदाहरण में, विधि एक अपवाद को फेंकती है क्योंकि एक मान सेट नहीं किया गया है:
Optional optional = Optional.empty();
return optional.orElseThrow(IllegalArgumentException::new);
// throws IllegalArgumentException
अगर संदेश के साथ अपवाद की आवश्यकता होती है तो आप लैम्बडा सिंटैक्स का उपयोग कर सकते हैं:
optional.orElseThrow(() -> new IllegalArgumentException("Illegal"));
फ़िल्टर
filter()
का उपयोग यह इंगित करने के लिए किया जाता है कि आप मूल्य तभी पसंद करेंगे जब यह आपके विधेय से मेल खाता हो।
इसे ऐसे if (!somePredicate(x)) { x = null; }
जैसे if (!somePredicate(x)) { x = null; }
।
कोड उदाहरण:
String value = null;
Optional.ofNullable(value) // nothing
.filter(x -> x.equals("cool string"))// this is never run since value is null
.isPresent(); // false
String value = "cool string";
Optional.ofNullable(value) // something
.filter(x -> x.equals("cool string"))// this is run and passes
.isPresent(); // true
String value = "hot string";
Optional.ofNullable(value) // something
.filter(x -> x.equals("cool string"))// this is run and fails
.isPresent(); // false
आदिम संख्या प्रकारों के लिए वैकल्पिक कंटेनरों का उपयोग करना
OptionalDouble
, OptionalInt
और OptionalLong
की तरह काम Optional
है, लेकिन विशेष रूप से आदिम प्रकार रैप करने के लिए तैयार कर रहे हैं:
OptionalInt presentInt = OptionalInt.of(value);
OptionalInt absentInt = OptionalInt.empty();
क्योंकि संख्यात्मक प्रकारों का मूल्य होता है, अशक्त के लिए कोई विशेष हैंडलिंग नहीं होती है। खाली कंटेनरों की जाँच की जा सकती है:
presentInt.isPresent(); // Is true.
absentInt.isPresent(); // Is false.
इसी प्रकार, शॉर्टहैंड मूल्य प्रबंधन में सहायता के लिए मौजूद हैं:
// Prints the value since it is provided on creation.
presentInt.ifPresent(System.out::println);
// Gives the other value as the original Optional is empty.
int finalValue = absentInt.orElseGet(this::otherValue);
// Will throw a NoSuchElementException.
int nonexistentValue = absentInt.getAsInt();
यदि कोई मान मौजूद है तो केवल कोड चलाएँ
Optional<String> optionalWithValue = Optional.of("foo");
optionalWithValue.ifPresent(System.out::println);//Prints "foo".
Optional<String> emptyOptional = Optional.empty();
emptyOptional.ifPresent(System.out::println);//Does nothing.
एक आपूर्तिकर्ता का उपयोग करके लेज़ीली एक डिफ़ॉल्ट मान प्रदान करता है
सामान्य या orElse
विधि एक Object
लेती है, इसलिए आप आश्चर्यचकित हो सकते हैं कि यहां एक Supplier
प्रदान करने का विकल्प क्यों है ( orElseGet
विधि)।
विचार करें:
String value = "something";
return Optional.ofNullable(value)
.orElse(getValueThatIsHardToCalculate()); // returns "something"
यह अभी भी getValueThatIsHardToCalculate()
कॉल करेगा, हालांकि यह परिणाम के रूप में उपयोग नहीं किया जाता है क्योंकि वैकल्पिक खाली नहीं है।
इस दंड से बचने के लिए आप एक आपूर्तिकर्ता की आपूर्ति करते हैं:
String value = "something";
return Optional.ofNullable(value)
.orElseGet(() -> getValueThatIsHardToCalculate()); // returns "something"
इस तरह से getValueThatIsHardToCalculate()
केवल तभी कहा जाएगा जब Optional
खाली हो।
FlatMap
flatMap
map
समान है। अंतर को जावदोक द्वारा वर्णित किया गया है:
यह विधि
map(Function)
समान है, लेकिन प्रदान किया गया मैपर वह है जिसका परिणाम पहले से ही एकOptional
, और यदिflatMap
किया गया है, तोflatMap
इसे अतिरिक्तOptional
साथ लपेटता नहीं है।
दूसरे शब्दों में, जब आप एक विधि कॉल श्रृंखला में है कि रिटर्न एक Optional
, का उपयोग कर Optional.flatMap
नेस्टेड बनाने से बचा जाता है Optionals
।
उदाहरण के लिए, निम्न वर्ग दिए गए हैं:
public class Foo {
Optional<Bar> getBar(){
return Optional.of(new Bar());
}
}
public class Bar {
}
यदि आप Optional.map
उपयोग करते हैं, तो आपको एक नेस्टेड Optional
मिलेगा; यानी Optional<Optional<Bar>>
।
Optional<Optional<Bar>> nestedOptionalBar =
Optional.of(new Foo())
.map(Foo::getBar);
हालाँकि, यदि आप Optional.flatMap
उपयोग करते हैं, तो आपको एक सरल Optional
मिलेगा; यानी Optional<Bar>
।
Optional<Bar> optionalBar =
Optional.of(new Foo())
.flatMap(Foo::getBar);