আইপ্রেসেট () খারাপ না বলে ptionচ্ছিক.গেট () কেন খারাপ, তবে পুনরাবৃত্তিকারী নয়?


23

নতুন জাভা 8 স্ট্রিমগুলি এপিআই ব্যবহার করার সময় কোনও সংকলনের একটি নির্দিষ্ট উপাদান খুঁজতে, আমি এই জাতীয় কোড লিখি:

    String theFirstString = myCollection.stream()
            .findFirst()
            .get();

এখানে ইন্টেলিজি সতর্ক করে যে পেতে () প্রথমে ইস্প্রেস () পরীক্ষা না করে কল করা হয়।

তবে, এই কোড:

    String theFirstString = myCollection.iterator().next();

... কোন সতর্কতা দেয়।

এই দুটি কৌশলগুলির মধ্যে কি কিছু গভীর পার্থক্য রয়েছে, যা স্ট্রিমিং পদ্ধতির কোনও উপায়ে আরও "বিপজ্জনক" করে তোলে, ইজপ্রেসেট () কে প্রথমে কল না করে কখনই গেট () কল করা গুরুত্বপূর্ণ নয়? চারদিকে গুগল করা, আমি প্রোগ্রামাররা কীভাবে ptionচ্ছিক <> সাথে অসাবধান এবং সেগুলি () কখনই কল করতে পারে কল্পনা করতে পারে সে সম্পর্কে কথা বলার জন্য নিবন্ধগুলি পেয়েছি।

কথাটি হ'ল, আমার কোডটি বগি যেখানে রয়েছে তার কাছে যতটা সম্ভব আমার কাছে নিক্ষিপ্ত একটি ব্যতিক্রম পেতে চাই, যা কোনও উপাদান না পাওয়া গেলে এই ক্ষেত্রে আমি get () কল করছি। আমি চাই না যেমন অনর্থক রচনা লিখতে:

    Optional<String> firstStream = myCollection.stream()
            .findFirst();
    if (!firstStream.isPresent()) {
        throw new IllegalStateException("There is no first string even though I totally expected there to be! <sarcasm>This exception is much more useful than NoSuchElementException</sarcasm>");
    }
    String theFirstString = firstStream.get();

... যদি না পেয়ে () থেকে ব্যতিক্রমকে উস্কে দেওয়ার কিছু বিপদ না থাকে যা সম্পর্কে আমি অজানা?


কার্ল বিলেফেল্টের প্রতিক্রিয়া এবং হাল্কের মন্তব্য পড়ার পরে আমি বুঝতে পারলাম উপরে আমার ব্যতিক্রম কোডটি কিছুটা আনাড়ি, এখানে আরও ভাল কিছু:

    String errorString = "There is no first string even though I totally expected there to be! <sarcasm>This exception is much more useful than NoSuchElementException</sarcasm>";
    String firstString = myCollection.stream()
            .findFirst()
            .orElseThrow(() -> new IllegalStateException(errorString));

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


7
আপনার শেষ উদাহরণটি রূপে ব্যতিক্রমী অংশটি হ'ল আপনি যদি অ্যালেক্সট্রো ব্যবহার করেন তবে আরও সংক্ষিপ্তভাবে লেখা যেতে পারে - এবং এটি সমস্ত পাঠকদের কাছে পরিষ্কার হবে যে আপনি ব্যতিক্রমটি ছুঁড়ে মারতে চান।
হাল্ক

উত্তর:


12

প্রথমত, বিবেচনা করুন যে চেকটি জটিল এবং সম্ভবত তুলনামূলকভাবে সময় সাপেক্ষ। এটির জন্য কিছু স্থির বিশ্লেষণ প্রয়োজন এবং দুটি কলের মধ্যে বেশ কিছুটা কোড থাকতে পারে।

দ্বিতীয়ত, দুটি কন্সট্রাক্টরের আইডিয়োম্যাটিক ব্যবহার খুব আলাদা। আমি স্কালায় পুরো সময়ের প্রোগ্রাম করি যা Optionsজাভা এর চেয়ে অনেক বেশি ঘন ঘন ব্যবহার করে। আমি কোনও একক উদাহরণটি স্মরণ করতে পারি না যেখানে আমাকে একটি .get()অন ব্যবহার করতে হবে Option। আপনি প্রায় সবসময় Optionalআপনার ফাংশন থেকে ফিরে আসতে হবে, বা orElse()পরিবর্তে ব্যবহার করা উচিত। ব্যতিক্রম ছোঁড়ার চেয়ে অনুপস্থিত মানগুলি হ্যান্ডেল করার জন্য এগুলি অনেক উন্নত উপায়।

যেহেতু .get()সাধারণ ব্যবহারে খুব কমই কল করা উচিত, কোনও আইডিই যখন এটি .get()সঠিকভাবে ব্যবহৃত হয় কিনা তা দেখার জন্য কোনও জটিল চেক শুরু করার জন্য এটি অর্থবোধ করে । বিপরীতে, iterator.next()এটি একটি পুনরাবৃত্তির সঠিক এবং সর্বব্যাপী ব্যবহার is

অন্য কথায়, এটি একটির খারাপ হওয়ার বিষয় নয় এবং অন্যটি নয়, এটির একটি সাধারণ বিষয় যা এটির অপারেশনের জন্য মৌলিক এবং বিকাশকারী পরীক্ষার সময় এটির ব্যতিক্রম হওয়ার সম্ভাবনা রয়েছে এবং অন্যটি খুব কমই ব্যবহৃত হয় বিকাশকারী পরীক্ষার সময় একটি ব্যতিক্রম ছুঁড়ে ফেলার জন্য পর্যাপ্ত ব্যায়াম করা যেতে পারে না। এগুলি হ'ল ধরণের কেস যা আপনি আইডিই আপনাকে সতর্ক করতে চান।


এই ptionচ্ছিক ব্যবসায়ের সম্পর্কে আমার আরও জানতে হবে - আমি আমাদের ওয়েব অ্যাপ্লিকেশনটিতে অনেক কিছু করে এমন বস্তুর তালিকার ম্যাপিংয়ের একটি দুর্দান্ত উপায় হিসাবে আমি বেশিরভাগ জাভা 8 স্টাফ দেখেছি seen সুতরাং আপনি everywhereচ্ছিক <> গুলি সর্বত্র পাঠানোর কথা? এটি কিছুটা অভ্যস্ত হয়ে উঠবে, তবে এটি অন্য এসই পোস্ট! :)
টিভির ফ্র্যাঙ্ক

@ টিভির ফ্রাঙ্ক এটা এর কম যে তারা যে, তারা তোমাদের ফাংশন রয়েছে বলে ধরনের একটি মান রুপান্তর লিখতে অনুমতি দেয়, এবং আপনি তাদের চেইন সর্বত্র হতে অনুমিত করছি, এবং আরও mapবা flatMap। চেক Optionalদিয়ে সমস্ত কিছু বন্ধন করা এড়ানোর জন্য বেশিরভাগ দুর্দান্ত উপায় null
মরগেন

15

Containsচ্ছিক শ্রেণিটি ব্যবহার করার উদ্দেশ্যে যখন এটি এতে থাকা আইটেমটি উপস্থিত কিনা তা জানা যায় না। সতর্কতাটি প্রোগ্রামারদের অবহিত করার জন্য উপস্থিত রয়েছে যে একটি অতিরিক্ত সম্ভাব্য কোড পাথ রয়েছে যা তারা নিখুঁতভাবে পরিচালনা করতে সক্ষম হতে পারে। ধারণাটি হ'ল ব্যতিক্রমগুলি এড়ানো উচিত নয়। আপনি যে ব্যবহারের বিষয়টি উপস্থাপন করছেন তা সেটির জন্য নকশাকৃত নয়, এবং তাই সতর্কতাটি আপনার কাছে অপ্রাসঙ্গিক - যদি আপনি আসলে একটি ব্যতিক্রম নিক্ষেপ করতে চান তবে এগিয়ে যান এবং এটি অক্ষম করুন (যদিও কেবল এই লাইনের জন্য, বিশ্বব্যাপী নয় - আপনার হওয়া উচিত উদাহরণস্বরূপ উপস্থিত উদাহরণগুলি উদাহরণস্বরূপ হ্যান্ডেল করবেন কিনা সে বিষয়ে সিদ্ধান্ত নেওয়া এবং সতর্কতা আপনাকে এটি করতে মনে করিয়ে দেবে।

যুক্তিযুক্তভাবে, পুনরাবৃত্তিকারীদের জন্য অনুরূপ সতর্কতা উত্পন্ন করা উচিত। যাইহোক, এটি কখনও কখনও করা হয়নি, এবং এখন একটি যুক্ত করা সম্ভবত বিদ্যমান প্রকল্পগুলিতে অনেক বেশি সতর্কবার্তা হ'ল একটি ভাল ধারণা হতে পারে।

এছাড়াও মনে রাখবেন যে আপনার নিজস্ব ব্যতিক্রম নিক্ষেপ করা কেবলমাত্র একটি ডিফল্ট ব্যতিক্রমের চেয়ে বেশি কার্যকর হতে পারে, কী কী উপাদানটির অস্তিত্ব প্রত্যাশিত ছিল তার বিবরণ সহ তবে পরবর্তী সময়ে ডিবাগিংয়ে খুব কার্যকর হতে পারে না।


6

আমি একমত যে এগুলির মধ্যে কোনও অন্তর্নিহিত পার্থক্য নেই, তবে আমি একটি বৃহত ত্রুটি চিহ্নিত করতে চাই।

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

যদিও এটি বলা হচ্ছে, কোডের উভয় অংশই কোডের গন্ধ। এই অভিব্যক্তিগুলি অন্তর্নিহিত ডিজাইনের ত্রুটিগুলি এবং ভঙ্গুর কোড দেয় at

আপনি অবশ্যই দ্রুত ব্যর্থ হওয়ার ইচ্ছায় সঠিক, তবে কমপক্ষে আমার পক্ষে সমাধানটি কেবল এটি বন্ধ করে বাতাসে হাত নিক্ষেপ করা (বা স্ট্যাকের উপরে একটি ব্যতিক্রম) হতে পারে না।

আপনার সংগ্রহটি আপাতত অ-শূন্য হিসাবে পরিচিত হতে পারে তবে আপনি যা নির্ভর করতে পারবেন তার হ'ল ধরণ: Collection<T>- এবং এটি আপনাকে শূন্যতার গ্যারান্টি দেয় না। যদিও আপনি এখন এটি খালি খালি জানেন, তবুও একটি পরিবর্তিত প্রয়োজনীয়তার ফলে কোডের সম্মুখবর্তী কোডটি পরিবর্তিত হতে পারে এবং হঠাৎ আপনার কোডটি খালি সংগ্রহের দ্বারা আঘাত হানে।

এখন আপনি পিছনে চাপ দিতে এবং অন্যকে বলার জন্য নির্দ্বিধায় যে আপনার খালি খালি তালিকা পাওয়ার কথা ছিল। আপনি খুশি হতে পারেন যে আপনি যে 'ত্রুটি' দ্রুত পেয়েছেন। তবুও, আপনার কাছে সফ্টওয়্যারটির একটি ভাঙা অংশ রয়েছে এবং আপনার কোড পরিবর্তন করতে হবে।

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

সংকলকটি আপনার পক্ষে যথাসম্ভব কাজ করে যা আপনি একটি পাওয়ার স্ট্যাটিক-টাইপ চুক্তিতে যতটা সম্ভব নির্ভর করতে পারেন Collection<T>। যখন আপনার কোড কখনও এই চুক্তিকে লঙ্ঘন করে না (যেমন এই দুটি দুর্গন্ধযুক্ত কল চেইনের মধ্য দিয়ে) তখন আপনার কোড পরিবেশগত অবস্থার পরিবর্তনে খুব কম ভঙ্গুর হয়।

উপরের দৃশ্যে, আপনার কোডের জন্য খালি ইনপুট সংগ্রহের পরিবর্তনের ফলে কোনও ফলাফল হবে না। এটি কেবলমাত্র অন্য বৈধ ইনপুট এবং এভাবে এখনও সঠিকভাবে পরিচালনা করা হয়েছে।

এর ব্যয় হ'ল আপনাকে আরও ভাল ডিজাইনের জন্য সময় ব্যয় করতে হবে, যেমন ক) ঝুঁকির কোড ঝুঁকিপূর্ণ বা খ) অযৌক্তিকভাবে বিষয়গুলিকে ব্যতিক্রম ছুঁড়ে দিয়ে জটিল করে তোলা।

একটি চূড়ান্ত নোটে: যেহেতু সমস্ত আইডিই / সংকলকগণ পূর্ববর্তী পরীক্ষাগুলি () এর পরে ()। বা alচ্ছিক.জেট () কল সম্পর্কে সতর্ক করে না, এই জাতীয় কোডটি সাধারণত পর্যালোচনাতে ফ্ল্যাগ করা হয়। এটির জন্য মূল্যবান, আমি এই জাতীয় কোডটিকে একটি পর্যালোচনা পাস করার অনুমতি দেব না এবং পরিবর্তে একটি পরিষ্কার সমাধান দাবি করব।


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

চিহ্নিত করা. "তালিকা থেকে সম্পত্তি পি দিয়ে উপাদানটি চয়ন করুন" -> list.stream ()। ফিল্টার (পি) .ফাইন্ড ফার্স্ট () .. এবং আবারও আমরা প্রশ্ন জিজ্ঞাসা করতে বাধ্য হই "এটি যদি সেখানে না থাকে তবে?" .. প্রতিদিনের রুটি এবং মাখন। যদি এটি মান্টোটোরয় এবং "ঠিক সেখানে" - তবে কেন আপনি প্রথম স্থানটিতে অন্যান্য গুচ্ছগুলিতে এটি লুকিয়ে রেখেছিলেন?
ফ্রাঙ্ক

4
কারণ এটি এটি একটি তালিকা যা ডাটাবেস থেকে লোড করা হয়। সম্ভবত তালিকাটি একটি পরিসংখ্যান সংগ্রহ যা অন্য কোনও ফাংশনে জড়ো হয়েছিল: আমরা জানি আমাদের কাছে A, B এবং C অবজেক্ট রয়েছে, আমি বি এর জন্য যা কিছু আছে তার পরিমাণ খুঁজে পেতে চাই। অনেকগুলি বৈধ (এবং আমার প্রয়োগে, সাধারণ) ক্ষেত্রে।
টিভির ফ্র্যাঙ্ক

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