জাভা ভাল অনুশীলনে যখনই সম্ভব লাম্বদা এক্সপ্রেশন ব্যবহার করা যায়?


52

আমি সম্প্রতি জাভা ৮-তে প্রবর্তিত ল্যাম্বডা এক্সপ্রেশনটি আয়ত্ত করে ফেলেছি I

এটি কি ভাল অনুশীলন হিসাবে বিবেচিত হয়? বা তাদের পরিস্থিতি যেখানে কার্যকরী ইন্টারফেসের জন্য লাম্বদা ব্যবহার করা উপযুক্ত নয়?


122
"যখনই সম্ভব ভাল অভ্যাসের কৌশলটি ব্যবহার করছেন" এই প্রশ্নের উত্তরটির একমাত্র সঠিক উত্তর হ'ল না, যখনই সম্ভব সম্ভব নয়, তবে যখনই বুদ্ধিমান ব্যবহার করুন কৌশলটি ব্যবহার করুন
ডক ব্রাউন

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

@ ডকব্রাউন এটি উত্তর হতে হবে, মন্তব্য নয়।
gnasher729

1
@ gnasher729: অবশ্যই না।
ডক ব্রাউন

উত্তর:


116

বেশ কয়েকটি মানদণ্ড রয়েছে যা আপনাকে ল্যাম্বডা ব্যবহার না করার বিষয়টি বিবেচনা করা উচিত:

  • আকার একটি ল্যাম্বডা যত বড় হবে তত সহজে তার চারপাশের যুক্তি অনুসরণ করা আরও কঠিন করে তোলে।
  • পুনরাবৃত্তি পুনরাবৃত্তি যুক্তির জন্য একটি নামকৃত ফাংশন তৈরি করা ভাল, যদিও ছড়িয়ে থাকা খুব সাধারণ ল্যাম্বডাস পুনরাবৃত্তি করা ঠিক আছে।
  • নামকরণ আপনি যদি একটি দুর্দান্ত শব্দার্থক নামটি ভাবতে পারেন তবে পরিবর্তে আপনার এটি ব্যবহার করা উচিত, কারণ এটি আপনার কোডে অনেক স্পষ্টতা যুক্ত করে। আমি নাম মত কথা বলছি না priceIsOver100x -> x.price > 100নাম হিসাবে ঠিক পরিষ্কার। আমি এর মতো নামগুলি isEligibleVoterশর্তাবলীর একটি দীর্ঘ তালিকা প্রতিস্থাপন করে।
  • নেস্টিং নেস্টেড ল্যাম্বডাস সত্যিই পড়তে পারা সত্যিই শক্ত।

ওভারবোর্ডে যাবেন না। মনে রাখবেন, সফ্টওয়্যারটি সহজেই পরিবর্তিত হয়। সন্দেহ হলে, এটি উভয় উপায়ে লিখুন এবং দেখুন যা পড়া সহজ।


1
ল্যাম্বডা দিয়ে যে পরিমাণ ডেটা প্রক্রিয়া করা হয় তা বিবেচনা করাও গুরুত্বপূর্ণ, কারণ ল্যাম্বডাস অল্প পরিমাণে ডেটা প্রসেসিংয়ের পরিবর্তে অদক্ষ। এগুলি বড় ডেটা সেটগুলির সমান্তরালে সত্যই জ্বলজ্বল করে।
ক্রেগআর 8806

1
@ ক্রেগআর ৮৮০6 আমি মনে করি না যে এখানে পারফরম্যান্স একটি উদ্বেগ। কোনও বেনামি ফাংশন ব্যবহার করা বা ক্রিয়ামূলক ইন্টারফেসকে প্রসারিত একটি শ্রেণি তৈরি করা একই কার্যকারিতা অনুযায়ী হওয়া উচিত। যখন আপনি একটি অত্যাবশ্যক স্টাইল লুপের উপরে স্ট্রিমগুলি / উচ্চ-অর্ডার-ফাংশনগুলি এপিআই ব্যবহার করার বিষয়ে কথা বলছেন তখন পারফরম্যান্স বিবেচনার বিষয়টি বিবেচনা করা হয় তবে এই প্রশ্নে আমরা উভয় ক্ষেত্রেই কেবল আলাদা সিনট্যাক্স সহ ফাংশনাল ইন্টারফেস ব্যবহার করছি।
পুহলেন

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

সামগ্রিকভাবে এটি সত্যিই ভাল উত্তর is কোনও ল্যাম্বদার বিকল্প হিসাবে কোনও পদ্ধতি রেফারেন্সের ব্যবহার উল্লেখ করা কেবল এই গর্তটিতে আমি দেখতে পাচ্ছি।
মরগেন

3
সন্দেহ হলে, এটিকে উভয় উপায়েই লিখুন এবং অন্য কাউকে জিজ্ঞাসা করুন যিনি কোডটি বজায় রাখা সহজ যা এটি বজায় রাখা সহজ।
corsiKa

14

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


6
কোনও পদ্ধতি রেফারেন্স ব্যবহারের সম্ভাবনাটি ভুলে যাবেন না! ওরাকল ঠিক সেই কারণে পুরো জায়গায় জুড়ে স্থির পদ্ধতি এবং ডিফল্ট পদ্ধতি যুক্ত করেছে (এবং জাভা 9 তে আরও বেশি যুক্ত করছে)।
Jörg ডব্লু মিটাগ

13

আমি কার্ল বিলেফেল্টের উত্তর সমর্থন করি, তবে একটি সংক্ষিপ্ত সংযোজন প্রদান করতে চাই।

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

নেট নেট সম্পর্কে অবশ্যই সত্য। অগত্যা ল্যাম্বডাস আমাকে এড়াতে দেয় না, তবে পরিবর্তে আমি অন্য কিছু করলে অবশ্যই আমি কোনও অপরাধবোধ অনুভব করি না।
ব্যবহারকারী 1172763

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

1
@ ইউজার ১১72২7763। ভিজ্যুয়াল স্টুডিওতে, আপনি যদি সদস্য ভেরিয়েবলগুলি দেখতে চান তবে আমি দেখতে পেয়েছি যে ল্যাম্বদার প্রসঙ্গে না পৌঁছা পর্যন্ত আপনি কল স্ট্যাক ভ্রমণ করতে পারবেন।
জেভ স্পিটজ

6

ঘেরের সুযোগের স্থানীয় ভেরিয়েবলগুলিতে অ্যাক্সেস

কার্ল বিলেফেল্টের গৃহীত উত্তরটি সঠিক। আমি আরও একটি পার্থক্য যুক্ত করতে পারি:

  • ব্যাপ্তি

শ্রেণীর অভ্যন্তরে কোনও পদ্ধতির অভ্যন্তরে থাকা ল্যাম্বডা কোডটি সেই পদ্ধতি ও শ্রেণীর মধ্যে পাওয়া কোনও কার্যকরভাবে চূড়ান্ত ভেরিয়েবল অ্যাক্সেস করতে পারে ।

ফাংশনাল ইন্টারফেস প্রয়োগ করে এমন একটি ক্লাস তৈরি করা আপনাকে কলিং কোডের স্থিতিতে যেমন সরাসরি অ্যাক্সেস দেয় না।

করার জাভা টিউটোরিয়াল উদ্ধৃত (জোর খনি):

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

সুতরাং লম্বা কোডটি বের করার এবং এর নামকরণের সুবিধাগুলি থাকা সত্ত্বেও, আপনাকে অবশ্যই এটিকে বদ্ধকরণ পদ্ধতি এবং শ্রেণীর স্থানে সরাসরি অ্যাক্সেসের সরলতার বিপরীতে বিবেচনা করতে হবে।

দেখা:


4

এটি নিট-পিকিং হতে পারে, তবে অন্যান্য উত্তরে তৈরি করা সমস্ত চমৎকার পয়েন্টগুলিতে আমি যুক্ত করব:

সম্ভব হলে পদ্ধতি রেফারেন্সগুলি পছন্দ করুন । তুলনা করা:

employees.stream()
         .map(Employee::getName)
         .forEach(System.out::println);

বনাম

employees.stream()
         .map(employee -> employee.getName())
         .forEach(employeeName -> System.out.println(employeeName));

একটি পদ্ধতি রেফারেন্স ব্যবহার করে আপনি ল্যামডা এর যুক্তি (গুলি), যা সাধারণত অপ্রয়োজনীয় এবং / অথবা মত অলস নাম বাড়ে নাম প্রয়োজন সংরক্ষণ eবা x


0

ম্যাট ম্যাকহেনির উত্তরের ভিত্তিতে ল্যাম্বডা এবং পদ্ধতি রেফারেন্সের মধ্যে একটি সম্পর্ক থাকতে পারে যেখানে ল্যাম্বডাকে পদ্ধতি উল্লেখের সিরিজ হিসাবে পুনরায় লেখা যেতে পারে। উদাহরণ স্বরূপ:

employees.stream()
         .forEach(employeeName -> System.out.println(employee.getName()));

বনাম

employees.stream()
         .map(Employee::getName)
         .forEach(System.out::println);
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.