জাবাতে প্রতিটি () এর জন্য ল্যাম্বদা থেকে ফিরে আসুন


100

forEach()ল্যাম্বডা এক্সপ্রেশনগুলির সম্ভাবনাগুলি আবিষ্কার করার জন্য আমি প্রতিটি লুপকে ল্যাম্বডা- স্মৃতিগুলিতে পরিবর্তনের চেষ্টা করছি । নিম্নলিখিতটি সম্ভব বলে মনে হচ্ছে:

ArrayList<Player> playersOfTeam = new ArrayList<Player>();      
for (Player player : players) {
    if (player.getTeam().equals(teamName)) {
        playersOfTeam.add(player);
    }
}

লাম্বদা সহ forEach()

players.forEach(player->{if (player.getTeam().equals(teamName)) {playersOfTeam.add(player);}});

কিন্তু পরেরটি কাজ করে না:

for (Player player : players) {
    if (player.getName().contains(name)) {
        return player;
    }
}

ল্যাম্বদা সহ

players.forEach(player->{if (player.getName().contains(name)) {return player;}});

শেষ লাইনের বাক্য গঠনে কিছু ভুল আছে নাকি forEach()পদ্ধতি থেকে ফিরে আসা অসম্ভব ?


আমি এখনও ল্যাম্বডাসের অভ্যন্তরগুলির সাথে খুব বেশি পরিচিত নই, তবে আমি যখন নিজেকে প্রশ্নটি করি: "আপনি কী থেকে ফিরে আসবেন?", আমার প্রাথমিক সন্দেহটি হবে যে এটি পদ্ধতি নয় not
গিম্বি

4
@ জিম্বি হ্যাঁ, returnএকটি বিবৃতিতে লাম্বদা ল্যাম্বডা থেকেই ফিরে আসে, ল্যাম্বডা বলে কিছু নয়। ইয়ান রবার্টসের উত্তরেfindFirst দেখানো হিসাবে একটি স্ট্রিম শীঘ্রই ("শর্ট সার্কিট") ব্যবহার বন্ধ করুন ।
স্টুয়ার্ট মার্কস

উত্তর:


122

returnসেখানে ল্যামডা অভিব্যক্তি থেকে বদলে ধারণকারী পদ্ধতি থেকে ফিরে করা হয়। পরিবর্তে আপনার স্ট্রিমের forEachপ্রয়োজন filter:

players.stream().filter(player -> player.getName().contains(name))
       .findFirst().orElse(null);

এখানে filterস্ট্রিমটিকে সেই আইটেমগুলিতে সীমাবদ্ধ করে যা প্রিডিটিকের সাথে মেলে এবং findFirstতারপরে Optionalপ্রথম মিলের এন্ট্রি সহ একটি ফিরিয়ে দেয় ।

এটি লুপের পদ্ধতির চেয়ে কম দক্ষ দেখায় তবে বাস্তবে findFirst()শর্ট সার্কিট করতে পারে - এটি পুরো ফিল্টারড স্ট্রিম তৈরি করে না এবং এরপরে একটি উপাদান বের করে না, বরং এটি যতগুলি উপাদান প্রয়োজন ঠিক ততগুলি ফিল্টার করে to প্রথম মিল খুঁজে পাওয়া যায়। আপনি যদি প্রয়োজনীয়ভাবে (অর্ডার করা) স্ট্রিম থেকে প্রথম ম্যাচিং প্লেয়ারটি না পেয়ে কেবল কোনও মিলে যাওয়া আইটেমের বিষয়ে যত্নবান findAny()হন findFirst()তবে পরিবর্তে আপনি এটিও ব্যবহার করতে পারেন । সমান্তরালতা জড়িত থাকে যখন এটি আরও ভাল দক্ষতার জন্য অনুমতি দেয়।


ধন্যবাদ, আমি যা খুঁজছিলাম! জাভা 8 তে এক্সপ্লোর করার জন্য অনেক নতুন বলে মনে হচ্ছে :)
সামুটাম

10
যুক্তিসঙ্গত, তবে আমি আপনাকে orElse(null)একটি এ ব্যবহার না করার পরামর্শ দিচ্ছি Optional। এর মূল বিষয় Optionalহ'ল ওভারলোডিং নাল (যা এনপিইগুলিতে বাড়ে) এর পরিবর্তে কোনও মানের উপস্থিতি বা অনুপস্থিতি নির্দেশ করার একটি উপায় সরবরাহ করা provide আপনি যদি optional.orElse(null)এটি ব্যবহার করেন তবে নালার সাথে সমস্ত সমস্যা ফিরে কিনে। আপনি কেবলমাত্র যদি আপনি কলারকে সংশোধন করতে না পারেন এবং এটি সত্যিই নালার প্রত্যাশা করে তবে আমি এটি ব্যবহার করব।
স্টুয়ার্ট মার্কস

4
@ স্টার্টমার্কস প্রকৃতপক্ষে, পদ্ধতির রিটার্নের ধরণটিকে Optional<Player>সংশোধন করা প্রবাহের দৃষ্টান্তের সাথে মানানসই আরও প্রাকৃতিক উপায়। আমি কেবল ল্যাম্বডাস ব্যবহার করে কীভাবে বিদ্যমান আচরণের সদৃশ করব তা দেখানোর চেষ্টা করছিলাম।
ইয়ান রবার্টস

(অংশ অংশ: অংশ) যদি (! part.isEmpty ()) মিথ্যা ফেরত দেয়; আমি আশ্চর্য কি আসলে খাটো। এবং পরিষ্কার। জাভা প্রবাহ এপিআই সত্যই জাভা ভাষা এবং জাভা পরিবেশকে ধ্বংস করেছে। 2020 সালে যে কোনও জাভা প্রকল্পে কাজ করার জন্য দুঃস্বপ্ন
মিমি

17

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

আপনার লাইন বাই লাইনের ভিত্তিতে বিদ্যমান কোডটি কখনই জাভা 8 কোডে রূপান্তর করা উচিত নয় , আপনার বৈশিষ্ট্যগুলি নিষ্কাশন করা উচিত এবং সেগুলি রূপান্তর করা উচিত।

আপনার প্রথম ক্ষেত্রে আমি যা চিহ্নিত করেছি তা হ'ল:

  • আপনি যদি কোনও ইনপুট কাঠামোর উপাদানগুলিকে কোনও আউটপুট তালিকায় যোগ করতে চান তবে তারা কিছু প্রাক্কলকের সাথে মেলে।

আসুন দেখুন আমরা কীভাবে এটি করি, আমরা নিম্নলিখিতটি দিয়ে এটি করতে পারি:

List<Player> playersOfTeam = players.stream()
    .filter(player -> player.getTeam().equals(teamName))
    .collect(Collectors.toList());

আপনি এখানে কি করছেন:

  1. আপনার ইনপুট কাঠামোটিকে একটি স্ট্রিমে পরিণত করুন (আমি এখানে ধরে নিচ্ছি যে এটি টাইপযুক্ত Collection<Player>, এখন আপনার একটি রয়েছে Stream<Player>
  2. একটি দিয়ে সমস্ত অযাচিত উপাদানগুলিকে ফিল্টার করুন Predicate<Player>, প্রতিটি খেলোয়াড়কে বুলিয়ানকে ম্যাপিং করে সত্য রাখতে চাইলে এটি রাখা উচিত।
  3. এর মাধ্যমে ফলাফলের উপাদানগুলিকে একটি তালিকায় সংগ্রহ করুন, এ এর ​​মাধ্যমে Collectorআমরা এখানে স্ট্যান্ডার্ড লাইব্রেরি সংগ্রহকারীদের মধ্যে একটি ব্যবহার করতে পারি, যা Collectors.toList()

এটি আরও দুটি পয়েন্ট অন্তর্ভুক্ত করে:

  1. ইন্টারফেসের বিরুদ্ধে কোড, তাই List<E>ওভার বিরুদ্ধে কোড ArrayList<E>
  2. টাইপ প্যারামিটারের জন্য হীরা সূচনা ব্যবহার করুন new ArrayList<>(), আপনি সর্বোপরি জাভা 8 ব্যবহার করছেন।

এখন আপনার দ্বিতীয় পয়েন্ট:

আপনি আবার বৃহত্তর ছবিটির দিকে না তাকিয়ে জাভাস্ত্রের উত্তরাধিকারের কিছু জাভাতে রূপান্তর করতে চান। এই অংশটি ইতিমধ্যে @ ইয়ান রবার্টস দ্বারা জবাব দেওয়া হয়েছে , যদিও আমি মনে করি যে players.stream().filter(...)...তিনি তাঁর পরামর্শ অনুসারে আপনার কাজ করা উচিত।


6

আপনি যদি বুলিয়ান মানটি ফিরিয়ে দিতে চান তবে আপনি এই জাতীয় কিছু ব্যবহার করতে পারেন (ফিল্টারের চেয়ে অনেক দ্রুত):

players.stream().anyMatch(player -> player.getName().contains(name));


1

আপনি একটি ব্যতিক্রম নিক্ষেপ করতে পারেন:

বিঃদ্রঃ:

পাঠযোগ্যতার জন্য স্ট্রিমের প্রতিটি ধাপ নতুন লাইনে তালিকাবদ্ধ করা উচিত।

players.stream()
       .filter(player -> player.getName().contains(name))
       .findFirst()
       .orElseThrow(MyCustomRuntimeException::new);

যদি আপনার যুক্তিটি শিথিলভাবে "ব্যতিক্রমযুক্ত চালিত" হয় যেমন আপনার কোডে একটি জায়গা রয়েছে যা সমস্ত ব্যতিক্রম ধরা পড়ে এবং পরবর্তী সিদ্ধান্ত নেওয়ার সিদ্ধান্ত নেয়। কেবলমাত্র ব্যতিক্রম চালিত বিকাশ ব্যবহার করুন যখন আপনি নিজের কোড বেসকে বহুগুণে ছড়িয়ে দেওয়া এড়াতে পারেন try-catchএবং এই ব্যতিক্রমগুলি ছুঁড়ে দেওয়া খুব বিশেষ ক্ষেত্রে আপনি তাদের প্রত্যাশা করেন এবং সঠিকভাবে পরিচালনা করা যায়))

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