Ptionচ্ছিক জন্য ব্যবহার


271

এখন 6+ মাস বা তার বেশি সময় ধরে জাভা 8 ব্যবহার করা হয়েছে, আমি নতুন এপিআই পরিবর্তনগুলি নিয়ে বেশ খুশি। এক স্থান আমি এখনও আত্মবিশ্বাসী নই যখন ব্যবহার করা Optional। আমার মনে হয় এটি যে nullকোনও জায়গায় পাওয়া যেতে পারে এবং এটি কোথাও নেই it

আমি যখন এটি ব্যবহার করতে পারি তখন অনেকগুলি পরিস্থিতি মনে হয় এবং আমি কখনই নিশ্চিত নই যে এটির সুবিধা (পাঠযোগ্যতা / নাল সুরক্ষা) যুক্ত হয়েছে বা কেবল অতিরিক্ত ওভারহেডের কারণ রয়েছে।

সুতরাং, আমার কয়েকটি উদাহরণ রয়েছে এবং আমি Optionalউপকারী কিনা সে সম্পর্কে সম্প্রদায়ের চিন্তাগুলিতে আগ্রহী ।

1 - পাবলিক পদ্ধতি হিসাবে রিটার্ন টাইপ যখন পদ্ধতিটি ফিরে আসতে পারে null:

public Optional<Foo> findFoo(String id);

2 - প্যারামটি যখন হতে পারে কোনও পদ্ধতি প্যারামিটার হিসাবে null:

public Foo doSomething(String id, Optional<Bar> barOptional);

3 - একটি শিমের alচ্ছিক সদস্য হিসাবে:

public class Book {

  private List<Pages> pages;
  private Optional<Index> index;

}

4 - ইন Collections:

সাধারণভাবে আমি মনে করি না:

List<Optional<Foo>>

কিছু যুক্ত করে - বিশেষত যেহেতু কেউ মান ইত্যাদি filter()মুছে ফেলার জন্য ব্যবহার করতে পারে nullতবে Optionalসংগ্রহগুলিতে কি কোনও ভাল ব্যবহার রয়েছে ?

কোন মামলা আমি মিস করেছি?


2
আমি দরকারী মনে করি একটি ক্ষেত্রে উদাহরণস্বরূপ, যদি আপনার বিকল্পের মানচিত্র থাকে। উদাহরণস্বরূপ Map<Character, String>। যদি কোন প্রতিকল্পন আমি এই ব্যবহার করতে পারেন: Optional.ofNullable(map.get(c)).orElse(String.valueOf(c))। এছাড়াও নোট করুন যে Optional.fromNullable(map.get(c)).or(String.valueOf(c));
ptionচ্ছিকটি

3
এছাড়াও, সংগ্রহে, ভাল, সংগ্রহগুলি নাল মানকে অনুমতি দেয় না! Ptionচ্ছিক এখানে বিল ফিট করে। এবং আপনি .filter(Optional::absent)"নাল মান" আউট করতে পারেন

2
সব সততা ইন @fge আমি মনে করি ধারণা ঐচ্ছিক আসলে FP থেকে গৌন করা হয়।
ভিএইচ-এনজেডজেড 4:14

2
@fge এর সাথে getOrDefault()কি আরও ভাল প্রকাশ করা যায় না ?
জিম গ্যারিসন

উত্তর:


206

এর মূল বিষয়টি Optionalহ'ল কোনও ফাংশনের কোনও ফেরতের মানের অনুপস্থিতি নির্দেশ করার জন্য একটি মান প্রদান করা means এই আলোচনা দেখুন । এটি কলকারীকে সাবলীল পদ্ধতি কলগুলির একটি শৃঙ্খলা চালিয়ে যাওয়ার অনুমতি দেয়।

এটা হল সবচেয়ে ঘনিষ্ঠভাবে মিলে যায় ব্যবহারের ক্ষেত্রে # 1 ওপি প্রশ্নের হবে। যদিও, কোনও মান অনুপস্থিতি শূন্যের চেয়ে আরও সুনির্দিষ্ট সূত্র কারণ যেহেতু এমন কোনও কিছুই শূন্যIntStream.findFirst হতে পারে না।

ব্যবহারের ক্ষেত্রে # 2 , কোনও পদ্ধতিতে একটি argumentচ্ছিক যুক্তি পাস করার জন্য, এটি কাজ করা যেতে পারে, তবে এটি বরং আনাড়ি। ধরুন আপনার কাছে এমন একটি পদ্ধতি রয়েছে যা একটি স্ট্রিং পরে anচ্ছিক দ্বিতীয় স্ট্রিংয়ের পরে থাকে। Optionalদ্বিতীয় আর্গ হিসাবে একটি গ্রহণ করার ফলে এই কোডের ফলাফল হবে:

foo("bar", Optional.of("baz"));
foo("bar", Optional.empty());

এমনকি নাল গ্রহণ করা আরও ভাল:

foo("bar", "baz");
foo("bar", null);

সম্ভবত সবচেয়ে বেশি বোঝা একটি ওভারলোডেড পদ্ধতি থাকা যা একটি একক স্ট্রিং আর্গুমেন্ট গ্রহণ করে এবং দ্বিতীয়টির জন্য একটি ডিফল্ট সরবরাহ করে:

foo("bar", "baz");
foo("bar");

এটির সীমাবদ্ধতা রয়েছে তবে এটি উপরের যে কোনওটির তুলনায় অনেক সুন্দর।

ব্যবহারের ক্ষেত্রে # 3 এবং # 4 , একটি থাকারOptional একটি ডাটা স্ট্রাকচার একটি বর্গ মাঠে বা, API- এর অপব্যবহার বিবেচনা করা হয়। প্রথমত, এটি Optionalশীর্ষে বর্ণিত মূল নকশার লক্ষ্যের বিরুদ্ধে যায় । দ্বিতীয়ত, এটি কোনও মান যোগ করে না।

একটিতে মানটির অনুপস্থিতি মোকাবেলার জন্য তিনটি উপায় রয়েছে Optional : বিকল্প মানের সরবরাহ করা, বিকল্প মান সরবরাহ করতে কোনও ফাংশন কল করা, বা একটি ব্যতিক্রম ছুঁড়ে ফেলার জন্য। আপনি যদি কোনও ক্ষেত্রের মধ্যে সঞ্চয় করছেন তবে আপনি এটি সূচনা বা অ্যাসাইনমেন্টের সময় করবেন। যদি আপনি কোনও তালিকায় মান যুক্ত করে থাকেন, যেমন ওপি উল্লেখ করেছে, আপনার কাছে কেবল মান যোগ না করার অতিরিক্ত পছন্দ রয়েছে, যার ফলে অনুপস্থিত মানগুলিকে "চাটুকার" করা যায় না।

আমি নিশ্চিত যে কেউ কেউ এমন কিছু বিতর্কিত মামলা নিয়ে আসতে পারে যেখানে তারা সত্যিই Optionalকোনও ক্ষেত্র বা সংগ্রহে কোনও সঞ্চয় করতে চায় তবে সাধারণভাবে এটি করা এড়ানো ভাল।


46
আমি # 3 এর সাথে একমত নই। Optionalযখন জিনিসগুলি সম্পন্ন করতে হয় বা উপস্থিতি বা মানের অভাবে কাজ করা হয় তখন ক্ষেত্র হিসাবে এটি কার্যকর হতে পারে ।
glglgl

15
আমি কেন দেখছি না কেন if(foo == null)অভ্যন্তরীণভাবে করা কেবল ক্ষেত্রটি সংরক্ষণের চেয়ে ভাল optional। এবং আমি দেখতে পাচ্ছি না কেন স্পষ্টভাবে getOptionalFoo()অভ্যন্তরীণভাবে কল করা কেবল ক্ষেত্রটিকে একটি হিসাবে সংরক্ষণ করার চেয়ে ভাল Optional। এছাড়াও, যদি একটি ক্ষেত্র হতে পারে nullএবং একটি ক্ষেত্র নাও হতে পারে তবে nullকেন সেগুলি তৈরি করে Optionalবা না করে সংকলকের সাথে তা জানান না Optional
মোগ্রোনালল

27
@ স্টার্টমার্কস, এটি এমন একটি জিনিস যা আমি যখন সমস্ত Optional<>বিশেষজ্ঞের কাছ থেকে শুনি তখন কেবল আমাকে বিস্মিত করে : " Optional<>কোনও জমিতে সংরক্ষণ করবেন না "। আমি সত্যিই এই সুপারিশটির বিষয়টি বোঝার চেষ্টা করছি। একটি ডোম গাছ বিবেচনা করুন যেখানে নোডের পিতা বা মাতা থাকতে পারে। এটি ব্যবহারের ক্ষেত্রে Node.getParent()ফিরে আসবে বলে মনে হচ্ছে Optional<Node>। আমি কি সত্যিই nullপ্রতিটি বার ফলাফল সংরক্ষণ এবং প্রত্যাশিত আশা করি ? কেন? এই অতিরিক্ত অদক্ষতা আমার কোডটি কুরুচিপূর্ণ দেখা ছাড়াও কী কিনে?
গ্যারেট উইলসন

7
অন্যদিকে, গ্রেট উইলসন, মনে করুন আপনার কাছে রয়েছে Optional<Node> getParent() { return Optional.ofNullable(parent); }। এটি ব্যয়বহুল দেখাচ্ছে কারণ এটি Optionalপ্রতিবারের জন্য বরাদ্দ করে! তবে যদি কলার তাৎক্ষণিকভাবে এটি প্যাক করে রাখে তবে অবজেক্টটি অত্যন্ত স্বল্পস্থায়ী এবং এডেন স্থান থেকে কখনই প্রচারিত হয় না। এটি সম্ভবত জেআইটির পলায়ন বিশ্লেষণের দ্বারাও নির্মূল করা যেতে পারে। নীচের লাইনের উত্তরটি বরাবরের মতো "এটি নির্ভর করে" তবে Optionalক্ষেত্রগুলিতে সম্ভাব্য মেমরির ব্যবহারকে বিকাশ করে এবং ডেটা স্ট্রাকচার ট্র্যাভারসালকে ধীর করে দেয়। এবং অবশেষে আমি মনে করি এটি কোডকে বিশৃঙ্খলা করে, তবে এটি স্বাদের বিষয়।
স্টুয়ার্ট

6
@ গ্যারেটওয়িলসন তাই আপনি কি এর জন্য ব্লগ লিখেছেন? আমি এতে আগ্রহী
হব

78

আমি গেমটি করতে দেরি করছি তবে এর মূল্য কী, আমি আমার 2 সেন্ট যোগ করতে চাই। তারা ডিজাইন লক্ষ্যটিরOptional বিরুদ্ধে যায় , যা স্টুয়ার্ট মার্কসের উত্তর দ্বারা সংক্ষিপ্তসারিত হয় , তবে আমি এখনও তাদের বৈধতা সম্পর্কে নিশ্চিত (অবশ্যই)।

Whereচ্ছিক সর্বত্র ব্যবহার করুন

সাধারণভাবে

আমি ব্যবহার সম্পর্কেOptional একটি সম্পূর্ণ ব্লগ পোস্ট লিখেছি তবে এটি মূলত এটিতে আসে:

  • সম্ভাব্যতা যেখানেই সম্ভব বিকল্পতা এড়াতে আপনার ক্লাসগুলি ডিজাইন করুন
  • সমস্ত অবশিষ্ট ক্ষেত্রে ডিফল্টটি Optionalপরিবর্তে ব্যবহার করা উচিতnull
  • সম্ভবত এর জন্য ব্যতিক্রম করুন:
    • স্থানীয় পরিবর্তনশীল
    • ব্যক্তিগত পদ্ধতিতে মান এবং তর্কগুলি প্রদান করুন
    • কর্মক্ষমতা সমালোচনামূলক কোড ব্লক (কোন অনুমান, কোনও প্রোফাইলার ব্যবহার করুন)

প্রথম দুটি ব্যতিক্রম মোড়ক এবং আন-র্যাপিং রেফারেন্সগুলিতে অনুমিত ওভারহেডকে হ্রাস করতে পারে Optional । এগুলি এমনভাবে বেছে নেওয়া হয়েছে যে কোনও নাল কখনও আইনত একটি উদাহরণ থেকে অন্য ক্ষেত্রে প্রবেশ করতে পারে না।

নোট করুন যে এটি Optionalসংগ্রহের ক্ষেত্রে প্রায়শই কখনই মঞ্জুরি দেয় না যা প্রায় এস হিসাবে খারাপ null। শুধু এটা করবেন না। ;)

আপনার প্রশ্ন সম্পর্কিত

  1. হ্যাঁ.
  2. যদি ওভারলোডিং কোনও বিকল্প না হয় তবে হ্যাঁ।
  3. যদি অন্যান্য পদ্ধতির (সাবক্লাসিং, সাজসজ্জা, ...) কোনও বিকল্প না হয়, হ্যাঁ।
  4. অনুগ্রহ করে না!

সুবিধাদি

nullএটি করা আপনার কোড বেসে এর উপস্থিতি হ্রাস করে , যদিও এটি সেগুলি মুছে না। তবে এটি মূল বিষয়টিও নয়। অন্যান্য গুরুত্বপূর্ণ সুবিধা রয়েছে:

উদ্দেশ্য স্পষ্ট করে

ব্যবহার Optional স্পষ্টভাবে প্রকাশ করে যে চলকটি ভাল, optionচ্ছিক। আপনার কোড বা আপনার এপিআই এর গ্রাহক যেকোন পাঠককে এই সত্যের সাথে মারবে যে সেখানে কিছুই নেই এবং মানটি অ্যাক্সেস করার আগে একটি চেক প্রয়োজন।

অনিশ্চয়তা দূর করে

ঘটনার Optionalঅর্থ ছাড়া nullঅস্পষ্ট। এটি কোনও রাষ্ট্রের আইনী প্রতিনিধিত্ব (দেখুন Map.get) বা অনুপস্থিত বা ব্যর্থ সূচনার মতো বাস্তবায়ন ত্রুটি হতে পারে।

এর অবিরাম ব্যবহারের সাথে এটি নাটকীয়ভাবে পরিবর্তিত হয় Optional। এখানে, ইতিমধ্যে nullত্রুটির উপস্থিতিটি একটি বাগের উপস্থিতি নির্দেশ করে। (কারণ যদি মানটি নিখোঁজ হওয়ার অনুমতি দেওয়া হত তবে একটি Optionalব্যবহার করা যেত)) এটির অর্থের প্রশ্নটি nullইতিমধ্যে উত্তর প্রাপ্ত হওয়ায় এটি একটি নাল পয়েন্টার ব্যতিক্রমকে ডিবাগ করা সহজ করে তোলে ।

আরও নাল চেক

এখন nullআর কিছুই হতে পারে না, এটি সর্বত্র প্রয়োগ করা যেতে পারে। টীকাগুলি, জোর দেওয়া বা সরল চেকগুলি সহ, আপনার এই যুক্তি বা সেই রিটার্নের ধরণটি নাল হতে পারে কিনা তা নিয়ে আপনাকে কখনই চিন্তা করতে হবে না। এটা পারে না!

অসুবিধেও

অবশ্যই, কোনও রূপালী বুলেট নেই ...

কর্মক্ষমতা

অতিরিক্ত উদাহরণে মান আবদ্ধ করা (বিশেষত আদিম) কর্মক্ষমতা হ্রাস করতে পারে। শক্ত লুপগুলিতে এটি লক্ষণীয় হতে পারে বা আরও খারাপ হতে পারে।

নোট করুন যে সংকলকটি এর স্বল্পকালীন লাইফটাইমগুলির জন্য অতিরিক্ত রেফারেন্সটি ছিন্ন করতে সক্ষম হতে পারে Optional। জাভাতে 10 মান ধরণের আরও জরিমানা হ্রাস বা অপসারণ করতে পারে।

ধারাবাহিকতাতে

Optionalserializable নয় কিন্তু একটি কার্যসংক্রান্ত মাত্রাতিরিক্ত জটিল নয়।

Invariance

জাভাতে জেনেরিক প্রকারের অদম্যতার কারণে, যখন আসল মান প্রকারটিকে জেনেরিক ধরণের আর্গুমেন্টে চাপানো হয় তখন নির্দিষ্ট ক্রিয়াকলাপগুলি জটিল হয়ে ওঠে। এখানে একটি উদাহরণ দেওয়া হয়েছে ("প্যারামেট্রিক পলিমারফিজম" দেখুন)


আরেকটি অসুবিধা (বা সীমাবদ্ধতা) হ'ল আপনি ptionচ্ছিক (এক্সএক্সএক্সএক্স) উদাহরণগুলি বাছাই করতে পারবেন না, যদিও ওরাকল স্পষ্টভাবে এই বিধিনিষেধটি ইচ্ছাকৃতভাবে চাপিয়ে দিয়েছিলেন। এই ক্লাসগুলি কেবলমাত্র নির্দিষ্ট পরিস্থিতিতে ব্যবহার করা উচিত, এবং বিকাশকারী সঠিক কাজ করবে তা ধরে নিয়েই এই ক্লাসগুলি উপলব্ধ করার বুদ্ধি সম্পর্কে আমি সংশয়বাদী। একটি সমস্যা সমাধানের ফলে অন্য সমস্যার কারণ হতে পারে। সম্ভবত "অনাকাঙ্ক্ষিত" উপায়ে egচ্ছিক (এক্সএক্সএক্সএক্স) ক্লাসগুলি ব্যবহার করার সময় বিকাশকারীকে সহায়তা করার জন্য সংকলক সতর্কতা থাকতে হবে (উদাহরণস্বরূপ পদ্ধতি পরামিতি হিসাবে, সংগ্রহের ক্ষেত্রে, নির্মাণকারী ইত্যাদিতে) যদি তা সত্যই ব্যবহারের উদ্দেশ্যে না হয়?
স্কোমিসা

4 সম্পর্কে সংগ্রহে optionals: এটা আসলে কখনও কখনও সঞ্চয় optionals দরকারী Listসে। এই ক্ষেত্রে যখন এটি গুরুত্বপূর্ণ যখন নির্দিষ্ট উপাদান একটি নির্দিষ্ট সূচীতে অবস্থিত, তবে উপাদান উপস্থিত থাকতে পারে বা নাও হতে পারে। এটি স্পষ্টভাবে একটি List<Optional<T>>প্রকারের দ্বারা জানানো হয় । অন্যদিকে যদি এটি কেবল গুরুত্বপূর্ণ যে কোন বস্তু যা কিছু সংগ্রহের সদস্য হয় তবে কোনও বক্তব্য নেই।
লই

3
আমি মনে করি ইউজ-কেস # 2 এখনও খুব প্রশ্নবিদ্ধ। একটি Optionalএকটি পদ্ধতি মধ্যে প্রেরণ করা হচ্ছে হতে পারে null। তাহলে আপনি কি অর্জন করেছেন? এখন আপনার কাছে দুটি চেক করতে হবে। স্ট্যাকওভারফ্লো.com
ডেভিড ভি

2
@ ডেভিডভি আমার দেওয়া সুবিধার তালিকার দিকে তাকান - সেগুলিও সেই ক্ষেত্রে প্রযোজ্য। তদুপরি, আপনি যদি সব কিছু চালিয়ে যান Optional(যদি আপনি এটি আর্গুমেন্ট হিসাবে পাস করতে ইচ্ছুক হন তবে এটি হওয়া উচিত) nullকখনই আইনগত মূল্য নয়। সুতরাং একটি সুস্পষ্ট প্যারামিটার সহ একটি পদ্ধতি কল nullকরা স্পষ্টতই একটি ভুল।
নিকোলাই

28

ব্যক্তিগতভাবে, আমি ইন্টেলিজির কোড পরিদর্শন সরঞ্জামটি ব্যবহার করতে @NotNullএবং @Nullableচেকগুলি ব্যবহার করতে পছন্দ করি কারণ এগুলি বেশিরভাগ সময় সংকলন করে থাকে (কিছু রানটাইম চেক থাকতে পারে) কোড পাঠযোগ্যতা এবং রানটাইম পারফরম্যান্সের ক্ষেত্রে এটির ওভারহেড কম থাকে। এটি ptionচ্ছিক ব্যবহারের মতো কঠোর নয়, তবে এই দৃor়তার অভাবটিকে শালীন ইউনিট পরীক্ষাগুলি দ্বারা সমর্থন করা উচিত।

public @Nullable Foo findFoo(@NotNull String id);

public @NotNull Foo doSomething(@NotNull String id, @Nullable Bar barOptional);

public class Book {

  private List<Pages> pages;
  private @Nullable Index index;

}

List<@Nullable Foo> list = ..

এটি জাভা 5 এর সাথে কাজ করে এবং মানগুলিকে মোড়ানোর ও আনরপ করার দরকার নেই। (বা মোড়কের বস্তু তৈরি করুন)


7
আহ, এই আইডিইএ টিকা আছে? আমি @Nonnull
জেএসআর

@fge এ বিষয়ে মানদণ্ডের অভাব রয়েছে, তবে আমি বিশ্বাস করি যে সরঞ্জামগুলি সাধারণত কনফিগার করা যায় এবং আপনাকে শেষ করতে হবে না@Nonnull @NotNull etc
পিটার লরে

4
হ্যাঁ এটি সত্য; ধারণা থেকে (13.x) তিনটি ভিন্ন পছন্দ দেয় ... ধুস, আমি সবসময় JSR 305 ব্যবহার শেষ anywa
fge

3
আমি জানি এটি পুরানো, তবে টীকাগুলি এবং সরঞ্জামগুলি সম্পর্কে আলোচনা স্ট্যাকওভারফ্লো / প্রশ্ন / 35892063/… - এর একটি লিঙ্কের দাবিদার - যা বিটিডব্লিউটি জাভা ৮
স্টিফান হার্মান

25

আমি মনে করি পেয়ারা ptionচ্ছিক এবং তাদের উইকি পৃষ্ঠা এটি বেশ ভালভাবে রেখেছিল:

নালীর নাম দেওয়া থেকে পঠনযোগ্যতা বৃদ্ধির পাশাপাশি ptionচ্ছিকের সবচেয়ে বড় সুবিধা হ'ল এর বোকা-প্রমাণ-নেস। আপনি যদি আপনার প্রোগ্রামটি একেবারে সংকলন করতে চান তবে এটি আপনাকে অনুপস্থিত কেস সম্পর্কে সক্রিয়ভাবে চিন্তা করতে বাধ্য করে, যেহেতু আপনাকে activeচ্ছিকভাবে সক্রিয়ভাবে আনপাট করতে হবে এবং address কেসটির সমাধান করতে হবে। নুল এটিকে ঝামেলাজনকভাবে সহজভাবে জিনিসগুলি ভুলে যাওয়া সহজ করে তোলে এবং যদিও ফাইন্ডব্যাগগুলি সহায়তা করে তবে আমরা মনে করি না যে এটি সমস্যাটিকে প্রায় ভালভাবে মোকাবেলা করে।

এটি বিশেষভাবে প্রাসঙ্গিক যখন আপনি মান উপস্থিত করতে পারেন যা "উপস্থিত" থাকতে পারে না। আপনি (এবং অন্যরা) ভুলে যাবেন এমন সম্ভাবনা অনেক বেশি যে আপনি অন্যান্য.সেমোডিংটি বাস্তবায়ন করার সময় অন্যান্য নীতিগত (ক, খ) এর চেয়ে নাল মান ফিরিয়ে দিতে পারবেন যে আপনি ভুলে যাবেন বলে মনে করছেন। Oচ্ছিক প্রত্যাবর্তন কলারের পক্ষে সেই কেসটি ভুলে যাওয়া অসম্ভব করে তোলে, যেহেতু তাদের কোডটি সংকলনের জন্য তাদের নিজেরাই বস্তুটি মোড়ক করতে হয়। -- (উৎস: পেয়ারা উইকি - নাল ব্যবহার এবং এড়ানো - কোন বিষয়টি? )

Optional কিছু ওভারহেড যুক্ত করেছে, তবে আমি মনে করি এর স্পষ্ট সুবিধা এটি তৈরি করা make স্পষ্ট করে দেওয়া যে কোনও বস্তু অনুপস্থিত থাকতে পারে এবং এটি প্রয়োগ করে যে প্রোগ্রামাররা পরিস্থিতি পরিচালনা করে। এটি প্রতিরোধ করে যে কেউ প্রিয়জনকে ভুলে যায়!= null চেকটি ।

2 এর উদাহরণ গ্রহণ করা , আমি মনে করি এটি লেখার চেয়ে অনেক বেশি স্বচ্ছ কোড:

if(soundcard.isPresent()){
  System.out.println(soundcard.get());
}

চেয়ে

if(soundcard != null){
  System.out.println(soundcard);
}

আমার জন্য, Optional আরও ভাল সত্যটি উপলব্ধি করে যে কোনও সাউন্ডকার্ড উপস্থিত নেই।

আপনার পয়েন্ট সম্পর্কে আমার 2:

  1. public Optional<Foo> findFoo(String id);- আমি এ সম্পর্কে নিশ্চিত নই হতে পারে আমি এমন একটি ফিরিয়ে দেব Result<Foo>যা হয়ত খালি বা একটিতে থাকতে পারে Foo। এটি একটি অনুরূপ ধারণা, তবে আসলে এটি নয়Optional
  2. public Foo doSomething(String id, Optional<Bar> barOptional);- আমি পিটার লরির উত্তর অনুসারে @ নুলাবল এবং একটি ফাইন্ডব্যাগ চেক পছন্দ করবো - এটি দেখুন এই আলোচনাটিও দেখুন
  3. আপনার বইয়ের উদাহরণ - আমি নিশ্চিত নই যে আমি অভ্যন্তরীণভাবে ptionচ্ছিকটি ব্যবহার করব, যা জটিলতার উপর নির্ভর করে। কোনও বইয়ের "এপিআই" এর জন্য আমি একটি ব্যবহার করবOptional<Index> getIndex() স্পষ্টভাবে ইঙ্গিত যে বইটিতে কোনও সূচক নাও থাকতে পারে।
  4. আমি সংগ্রহগুলিতে নাল মানকে অনুমতি না দিয়ে সংগ্রহগুলিতে এটি ব্যবহার করব না

সাধারণভাবে, আমি nullএস এর কাছাকাছি পাস কমানোর চেষ্টা করব । (একবার জ্বললে ...) আমি মনে করি উপযুক্ত বিমূর্ততা খুঁজে পাওয়া এবং সহকারী প্রোগ্রামারদের কাছে নির্দিষ্ট ফিরতি মূল্য আসলে কী উপস্থাপন করে তা নির্ধারণ করা উপযুক্ত।


15
আপনি লিখতেন soundcard.ifPresent(System.out::println)। কলিং isPresentশব্দার্থগতভাবে পরীক্ষা করার জন্য একই null
আরও ভাল অলিভার

আমার কাছে সমস্যাটি হ'ল ptionচ্ছিক ধরণের জিনিসগুলি এখনও শূন্য হতে পারে। সুতরাং প্রকৃতপক্ষে সম্পূর্ণ নিরাপদ থাকতে আপনাকে এমন কিছু করতে হবে if(soundcard != null && soundcard.isPresent())। এমন একটি এপিআই তৈরি করা যা একটি ptionচ্ছিক প্রত্যাবর্তন করে এবং নালও ফিরে আসতে পারে এমন কিছু আমি আশা করি কেউ কখনও করেনি।
সাইমন বাউমগার্ড-ওয়েল্যান্ডার

"আপনি যদি আপনার প্রোগ্রামটি একেবারে সংকলন করতে চান তবে এটি আপনাকে অনুপস্থিত কেস সম্পর্কে সক্রিয়ভাবে চিন্তা করতে বাধ্য করে, যেহেতু আপনাকে activeচ্ছিকভাবে সক্রিয়ভাবে আন-ল্যাপটপ করতে হবে এবং সেই মামলার সমাধান করতে হবে।" আমি কীভাবে এটি জোর করে তা সত্যিই নিশ্চিত নই, যদিও আমি জাভাতে পুরোপুরি কাজ করি না। আপনি জাভা কীভাবে মোড়ক মুছে ফেলতে এবং "ইস্প্রেস কেস সহজভাবে সংকলন করতে" পরীক্ষা করতে বাধ্য করতে যা করতে তা বোঝাতে পারেন?
পিষ্ট করুন

15

ওরাকল টিউটোরিয়াল থেকে :

Codeচ্ছিকর উদ্দেশ্যটি আপনার কোডবেসে প্রতিটি নাল রেফারেন্স প্রতিস্থাপন করা নয় বরং আরও ভাল এআইপি ডিজাইন করতে সহায়তা করা যা - কেবলমাত্র কোনও পদ্ধতির স্বাক্ষরটি পড়ে ব্যবহারকারীরা anচ্ছিক মান আশা করতে হবে কিনা তা বলতে পারবেন। তদুপরি, youচ্ছিক আপনাকে একটি মানের অভাবে মোকাবেলা করার জন্য একটি ptionচ্ছিককে সক্রিয়ভাবে আনপ্রেপ করতে বাধ্য করে; ফলস্বরূপ, আপনি আপনার কোডকে অনিচ্ছাকৃত নাল পয়েন্টার ব্যতিক্রমগুলির বিরুদ্ধে সুরক্ষা দিন।


3
এপিআইগুলি কেবল পদ্ধতির রিটার্ন অংশের জন্য? টাইপ-ইরেজরের কারণে বিকল্পগুলি পরামিতি হিসাবে ব্যবহার করা উচিত নয়? কখনও কখনও আমি কোনও পদ্ধতিতে অভ্যন্তরীণভাবে একটি ptionচ্ছিক ব্যবহার করি, একটি নল পরামিতি থেকে রূপান্তরিত হয় বা ক্ষেত্র হিসাবে নাল কনস্ট্রাক্টর প্যারামিটার থেকে আরম্ভ করি ... এখনও এটি চেষ্টা করার চেষ্টা করি যে এটি কেবল নাল হিসাবে রেখে দেওয়ার চেয়ে বেশি দরকারী কিনা - কারও কি চিন্তা আছে?
ycomp

@comp আপনি এই বা এই প্রশ্নে এই মামলাগুলি সম্পর্কে যথেষ্ট তথ্য খুঁজে পেতে পারেন । এই প্রশ্নগুলির উত্তরগুলি যে বিষয়ে জিজ্ঞাসা করা হয়েছিল তার চেয়ে অনেক বেশি বলে এবং অন্যান্য কেসগুলি কভার করে। আরও তথ্যের জন্য, আরও ব্রাউজ করুন বা আপনার নিজের প্রশ্ন জিজ্ঞাসা করুন, কারণ সম্ভবত আপনি এখানে খুব বেশি মনোযোগ পাবেন না। ; )
ctomek

8

1 - সর্বজনীন পদ্ধতি হিসাবে রিটার্ন টাইপ যখন পদ্ধতিটি বাতিল হয়ে যায়:

এখানে একটি ভাল নিবন্ধ যা # 1 ব্যবহারের উপযোগিতা দেখায়। সেখানে এই কোড

...
if (user != null) {
    Address address = user.getAddress();
    if (address != null) {
        Country country = address.getCountry();
        if (country != null) {
            String isocode = country.getIsocode();
            isocode = isocode.toUpperCase();
        }
    }
}
...

এটি রূপান্তরিত হয়

String result = Optional.ofNullable(user)
  .flatMap(User::getAddress)
  .flatMap(Address::getCountry)
  .map(Country::getIsocode)
  .orElse("default");

getচ্ছিককে সংশ্লিষ্ট গেটর পদ্ধতির রিটার্ন মান হিসাবে ব্যবহার করে।


2

এখানে ... টেস্টগুলির জন্য একটি আকর্ষণীয় ব্যবহার (আমি বিশ্বাস করি)।

আমি আমার একটি প্রকল্পের ভারী পরীক্ষার ইচ্ছা নিয়েছি এবং তাই আমি দৃ build়তা তৈরি করি; কেবলমাত্র আমাকে যাচাই করতে হবে এমন কিছু আছে এবং অন্যরাও যা করি না।

তাই আমি দৃsert়তা হিসাবে জিনিসগুলি তৈরি করি এবং সেগুলি যাচাই করতে একটি প্রতিরোধ ব্যবহার করি:

public final class NodeDescriptor<V>
{
    private final Optional<String> label;
    private final List<NodeDescriptor<V>> children;

    private NodeDescriptor(final Builder<V> builder)
    {
        label = Optional.fromNullable(builder.label);
        final ImmutableList.Builder<NodeDescriptor<V>> listBuilder
            = ImmutableList.builder();
        for (final Builder<V> element: builder.children)
            listBuilder.add(element.build());
        children = listBuilder.build();
    }

    public static <E> Builder<E> newBuilder()
    {
        return new Builder<E>();
    }

    public void verify(@Nonnull final Node<V> node)
    {
        final NodeAssert<V> nodeAssert = new NodeAssert<V>(node);
        nodeAssert.hasLabel(label);
    }

    public static final class Builder<V>
    {
        private String label;
        private final List<Builder<V>> children = Lists.newArrayList();

        private Builder()
        {
        }

        public Builder<V> withLabel(@Nonnull final String label)
        {
            this.label = Preconditions.checkNotNull(label);
            return this;
        }

        public Builder<V> withChildNode(@Nonnull final Builder<V> child)
        {
            Preconditions.checkNotNull(child);
            children.add(child);
            return this;
        }

        public NodeDescriptor<V> build()
        {
            return new NodeDescriptor<V>(this);
        }
    }
}

নোডএসর্ট ক্লাসে, আমি এটি করি:

public final class NodeAssert<V>
    extends AbstractAssert<NodeAssert<V>, Node<V>>
{
    NodeAssert(final Node<V> actual)
    {
        super(Preconditions.checkNotNull(actual), NodeAssert.class);
    }

    private NodeAssert<V> hasLabel(final String label)
    {
        final String thisLabel = actual.getLabel();
        assertThat(thisLabel).overridingErrorMessage(
            "node's label is null! I didn't expect it to be"
        ).isNotNull();
        assertThat(thisLabel).overridingErrorMessage(
            "node's label is not what was expected!\n"
            + "Expected: '%s'\nActual  : '%s'\n", label, thisLabel
        ).isEqualTo(label);
        return this;
    }

    NodeAssert<V> hasLabel(@Nonnull final Optional<String> label)
    {
        return label.isPresent() ? hasLabel(label.get()) : this;
    }
}

যার অর্থ আসক্তিটি সত্যই কেবল ট্রিগার হয় যদি আমি লেবেলটি পরীক্ষা করতে চাই!


2

Optionalবর্গ আপনাকে ব্যবহার এড়াতে nullএবং আরও ভাল বিকল্প সরবরাহ করতে দেয়:

  • এটি বিকাশকারীদের উপস্থিতি পরীক্ষা করার জন্য উত্সাহিত করে যাতে কিছু না পড়ে NullPointerException

  • এপিআই আরও ভাল নথিভুক্ত হয়ে গেছে কারণ এটি দেখা সম্ভব, কোথায় অনুমান হতে পারে এমন মানগুলি কোথায় প্রত্যাশা করা যায়।

Optionalবস্তুর সঙ্গে আরও কাজ জন্য সুবিধাজনক এপিআই প্রদান করে: isPresent(); get(); orElse(); orElseGet();orElseThrow(); map(); filter(); flatmap()

এছাড়াও, অনেকগুলি ফ্রেমওয়ার্ক সক্রিয়ভাবে এই ডেটা প্রকারটি ব্যবহার করে এবং তাদের এপিআই থেকে এটি ফিরিয়ে দেয়।


2

জাভাতে, আপনি কার্যকরী প্রোগ্রামিংয়ের আসক্ত না হলে কেবল সেগুলি ব্যবহার করবেন না।

পদ্ধতি আর্গুমেন্ট হিসাবে তাদের কোনও স্থান নেই (আমি একদিন কাউকে বলে দিচ্ছি যে একটি দিন আপনাকে শূন্য isচ্ছিক নয়, কেবল একটি alচ্ছিক .চ্ছিকভাবে পাস করবে)।

তারা প্রত্যাবর্তনের মানগুলির জন্য অর্থবোধ করে তবে তারা ক্লায়েন্ট শ্রেণিকে আমন্ত্রণ জানায় আচরণ-শৃঙ্খলা শৃঙ্খলা প্রসারিত করতে।

জাভা জাতীয় জরুরী ভাষায় এফপি এবং চেইনগুলির খুব কম জায়গা আছে কারণ এটি কেবল পড়া নয়, ডিবাগ করা খুব কঠিন করে তোলে। আপনি যখন লাইনে পা রাখেন, আপনি প্রোগ্রামের অবস্থা বা অভিপ্রায় জানতে পারবেন না; এটি বের করার জন্য আপনাকে পদক্ষেপ নিতে হবে (ধাপে ফিল্টার সত্ত্বেও কোডগুলি যেগুলি প্রায়ই আপনার হয় না এবং অনেকগুলি স্ট্যাক ফ্রেম গভীর হয় না) এবং আপনার যুক্ত কোড / ল্যাম্বডায় এটি থামতে পারে তা নিশ্চিত করতে আপনাকে প্রচুর ব্রেকপয়েন্ট যুক্ত করতে হবে, পরিবর্তে কেবল / অন্যথায় / তুচ্ছ লাইনে কল করার পরে

আপনি যদি ফাংশনাল প্রোগ্রামিং চান তবে জাভা বাদে অন্য কিছু বেছে নিন এবং আশা করুন যে এটি ডিবাগ করার জন্য আপনার কাছে সরঞ্জাম রয়েছে।


1

আমি মনে করি না যে বিকল্পগুলি সম্ভাব্য নাল মানগুলিকে ফিরিয়ে দেয় এমন পদ্ধতির একটি সাধারণ বিকল্প।

মূল ধারণাটি হ'ল: একটি মান অনুপস্থিতির অর্থ এই নয় যে এটি সম্ভাব্যভাবে ভবিষ্যতে উপলব্ধ। এটি FindById (-1) এবং FindById (67) এর মধ্যে পার্থক্য।

কলারের জন্য অপশনালগুলির প্রধান তথ্য হ'ল তিনি প্রদত্ত মানটি নাও গণনা করতে পারেন তবে এটি কোনও এক সময় পাওয়া যেতে পারে। সম্ভবত এটি আবার অদৃশ্য হয়ে যাবে এবং পরে আরও একবার ফিরে আসবে। এটি অন / অফ সুইচের মতো। আপনার কাছে লাইটটি চালু বা বন্ধ করার জন্য "বিকল্প" রয়েছে। তবে আপনার যদি সুইচ করার জন্য আলো না থাকে তবে আপনার কোনও বিকল্প নেই।

সুতরাং আমি যেখানেই পূর্বে নাল সম্ভাব্যরূপে প্রত্যাবর্তিত হয়েছিল সেখানে introduceচ্ছিকাগুলি প্রবর্তন করা খুব অসুবিধাজনক বলে মনে হচ্ছে। আমি এখনও নাল ব্যবহার করব, তবে কেবল গাছের গোড়া, অলস সূচনা এবং স্পষ্টত সন্ধানের পদ্ধতিগুলির মতো সীমাবদ্ধ অঞ্চলে।


0

মনে হয় Optionalযদি ঐচ্ছিক টাইপ টি মত একটি আদিম ধরনের শুধুমাত্র দরকারী int, long, char, ইত্যাদি "বাস্তব" শ্রেণীর জন্য, এটি আমার কাছে অর্থে দেখা যায় না হিসাবে আপনি একটি ব্যবহার করতে পারেন nullমান যাহাই হউক না কেন।

আমি মনে করি এটি এখান থেকে নেওয়া হয়েছিল (বা অন্য একটি অনুরূপ ভাষার ধারণা থেকে)।

Nullable<T>

সি # তে এটি Nullable<T>মান ধরণের মোড়ানোর জন্য অনেক আগে চালু হয়েছিল।


2
এটি Optionalআসলে
পেয়ারার একটি রিপোফ

2
@fge ঠিক আছে তবে যখন এটি সি # তে উপস্থিত ছিল (2005, MS.NET 2.0), কোনও পেয়ারা ছিল না, আমি মনে করি। এবং ... কে জানে সি # কোথা থেকে এসেছে।
পিটার.পেট্রভ

3
@fge "পেয়ারা Oচ্ছিক রিপফ" এটি বলার এক মজার উপায়, যেহেতু পেয়ারা ছেলেরা আলোচনায় অংশ নিয়েছিল, তাদের অভিজ্ঞতা সরবরাহ করেছিল এবং সাধারণত তাদের পক্ষে ছিল java.util.Optional
স্টুয়ার্ট মার্কস

6
@fge কোনও সন্দেহ নেই জাভা'র এপিআইগুলি পেয়ারা দ্বারা দৃ strongly়ভাবে প্রভাবিত হয়েছিল। আমি "রিপফ" দিয়ে ইস্যু নিচ্ছি যা চুরির মতো মনে হচ্ছে। পেয়ারা ছেলেরা জাভা ৮
স্টুয়ার্ট মার্কস

6
আপনি বিন্দু মিস করছি। নাল ফেরার পরিবর্তে returningচ্ছিক ব্যবহার করা উচিত। এটি একটি নুলপয়েন্টার এক্সসেপশন সম্ভাব্যভাবে ছুঁড়ে ফেলার চেয়ে নিরাপদ। দেখুন: oracle.com/technetwork/articles/java/…
কিলিজো

0

একটি ইটারেটর নকশা প্যাটার্ন একজন unmodifiable উদাহরণস্বরূপ অনুরূপ শব্দার্থবিদ্যা হয়েছে :Optional

  • এটি হতে পারে বা কোনও অবজেক্টের উল্লেখ করতে পারে না (যেমন দেওয়া হয়েছে isPresent())
  • get()যদি এটি কোনও অবজেক্টের উল্লেখ করে তবে এটি ব্যবহার করা যাবে না
  • তবে এটি ক্রমের পরবর্তী অবস্থানে উন্নীত করা যাবে না (এটির কোনও next()পদ্ধতি নেই)।

অতএব Optionalযেখানে আপনি আগে জাভা ব্যবহারের কথা ভেবে দেখেছিলেন সেই প্রসঙ্গে যেগুলি ফিরে আসতে বা পাস করার বিষয়ে বিবেচনা করুন Iterator


-1

জাভা এসই 8, জাভা.ইউটি.এল calledচ্ছিক নামক একটি নতুন ক্লাসের প্রবর্তন করেছে,

নাল মান সহ আপনি একটি খালি ptionচ্ছিক বা ptionচ্ছিক তৈরি করতে পারেন।

Optional<String> emptyOptional = Optional.empty(); 

এবং এখানে একটি নন-নাল মান সহ একটি ptionচ্ছিক:

String valueString = new String("TEST");
Optional<String> optinalValueString = Optional.of(valueString );

কোনও মূল্য উপস্থিত থাকলে কিছু করুন

এখন যেহেতু আপনার একটি objectচ্ছিক অবজেক্ট রয়েছে, আপনি মানগুলির উপস্থিতি বা অনুপস্থিতি স্পষ্টভাবে মোকাবেলার জন্য উপলভ্য পদ্ধতিগুলিতে অ্যাক্সেস করতে পারেন। পরিবর্তে নাল চেক করার কথা মনে রাখার পরিবর্তে:

String nullString = null;
if (nullString != null) {
    System.out.println(nullString);
}

আপনি নীচের মত ifPstream () পদ্ধতি ব্যবহার করতে পারেন:

Optional<String> optinalString= null;
optinalString.ifPresent(System.out::println);

package optinalTest;

import java.util.Optional;

public class OptionalTest {
    public Optional<String> getOptionalNullString() {
        return null;
//      return Optional.of("TESt");
    }

    public static void main(String[] args) {

        OptionalTest optionalTest = new OptionalTest();

        Optional<Optional<String>> optionalNullString = Optional.ofNullable(optionalTest.getOptionalNullString());

        if (optionalNullString.isPresent()) {
            System.out.println(optionalNullString.get());
        }
    }
}

এই কপিসপাস্টটি সস্তা খ্যাতি অর্জনের উদ্দেশ্যে, কিন্তু ওপির প্রশ্নের সাথে সম্পর্কিত নয়
স্টিংগার
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.