আমি কেন লুপের পরিবর্তে "ক্রিয়ামূলক ক্রিয়াকলাপগুলি" ব্যবহার করব?


39
for (Canvas canvas : list) {
}

নেটবিয়ানস আমাকে "ক্রিয়ামূলক ক্রিয়াকলাপ" ব্যবহার করার পরামর্শ দেয়:

list.stream().forEach((canvas) -> {
});

তবে কেন এটাকে প্রাধান্য দেওয়া হচ্ছে ? যদি কিছু হয় তবে এটি পড়া এবং বোঝা শক্ত। আপনি কল করছেন stream(), তারপরে forEach()পরামিতি সহ ল্যাম্বডা এক্সপ্রেশন ব্যবহার করছেন canvas। আমি দেখতে পাচ্ছি না যে forপ্রথম স্নিপেটে লুপের চেয়ে কোনও সুন্দর ।

স্পষ্টতই আমি কেবল নান্দনিকতার বাইরে কথা বলছি। সম্ভবত এখানে কোনও প্রযুক্তিগত সুবিধা রয়েছে যা আমি মিস করছি। এটা কি? পরিবর্তে আমি দ্বিতীয় পদ্ধতিটি কেন ব্যবহার করব?



15
আপনার বিশেষ উদাহরণে এটি পছন্দ করা হবে না।
রবার্ট হার্ভে

1
যতক্ষণ না একমাত্র অপারেশন প্রতিটি একক জন্য থাকে ততক্ষণ আমি আপনার সাথে একমত হতে চাই। আপনি পাইপলাইনে অন্যান্য ক্রিয়াকলাপগুলি যুক্ত করার সাথে সাথে, বা আপনি একটি আউটপুট ক্রম উত্পাদন করেন, তারপরে স্ট্রিম-পদ্ধতির পছন্দসই হয়ে যায়।
জ্যাকবিবি

পছন্দ করেছেন কেন না?
সারা

@ রবার্তাহারভে আমি ভালভাবে সম্মত হয়েছি আমি গৃহীত উত্তরটি সত্যিই দেখায় যে কীভাবে আরও জটিল মামলার জন্য সংস্করণটি পানির বাইরে ফুঁকছে, কিন্তু তুচ্ছ মামলায় কেন "জয়ের জন্য" আমি তা দেখতে পাচ্ছি না। আপনি এটি প্রকাশ করেছেন যেমন এটি স্বতঃস্ফূর্ত তবে আমি এটি দেখতে পাচ্ছি না, তাই আমি জিজ্ঞাসা করেছি।
সারা

উত্তর:


45

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

আপনার উদাহরণ খুব ব্যবহারিক নয়। ওরাকল সাইট থেকে নিম্নলিখিত কোডটি বিবেচনা করুন

List<Transaction> groceryTransactions = new Arraylist<>();
for(Transaction t: transactions){
  if(t.getType() == Transaction.GROCERY){
    groceryTransactions.add(t);
  }
}
Collections.sort(groceryTransactions, new Comparator(){
  public int compare(Transaction t1, Transaction t2){
    return t2.getValue().compareTo(t1.getValue());
  }
});
List<Integer> transactionIds = new ArrayList<>();
for(Transaction t: groceryTransactions){
  transactionsIds.add(t.getId());
}

স্ট্রিম ব্যবহার করে লেখা যেতে পারে:

List<Integer> transactionsIds = 
    transactions.stream()
                .filter(t -> t.getType() == Transaction.GROCERY)
                .sorted(comparing(Transaction::getValue).reversed())
                .map(Transaction::getId)
                .collect(toList());

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


5
মানচিত্র ফিউশন ( stream.map(f).map(g)stream.map(f.andThen(g))) বিল্ড / হ্রাস ফিউশন (যেমন কোনও পদ্ধতিতে একটি স্ট্রিম তৈরি করার পরে এটি ব্যবহার করে এমন অন্য পদ্ধতিতে প্রেরণ করার সময়, সংকলকটি স্ট্রিমটি নির্মূল করতে পারে) এবং স্ট্রিম ফিউশন (যা অনেক স্ট্রিম অপসকে ফিউজ করতে পারে ) এর মতো অপ্টিমাইজেশন কৌশল রয়েছে একসাথে একক আবশ্যক লুপ), যা স্ট্রিম অপারেশনগুলিকে আরও বেশি দক্ষ করে তুলতে পারে। এগুলি জিএইচসি হাস্কেল সংকলক এবং অন্য কিছু হাস্কেল এবং অন্যান্য কার্যকরী ভাষা সংকলকগুলিতে প্রয়োগ করা হয় এবং স্কালার জন্য পরীক্ষামূলক গবেষণা বাস্তবায়ন রয়েছে।
Jörg ডব্লু মিট্টাগ

কার্যক্ষম বনাম লুপ বিবেচনা করার সময় পারফরম্যান্স সম্ভবত কোনও ফ্যাক্টর নয় কারণ অবশ্যই সংকলক লুপের জন্য লুপ থেকে একটি কার্যকরী অপারেশনে রূপান্তর করতে পারে / যদি নেটবিনস পারে এবং এটি সর্বোত্তম পথ হিসাবে নির্ধারিত হয় তবে।
রায়ান 18

আমি দ্বিমত করব যে দ্বিতীয়টি আরও বেশি পঠনযোগ্য। কী চলছে তা নির্ধারণ করতে কিছুক্ষণ সময় লাগে। এটি দ্বিতীয় পদ্ধতিতে করার কোনও কার্যকারিতা সুবিধা আছে কারণ অন্যথায় আমি এটি দেখতে পাচ্ছি না?
বোক ম্যাকডোনগ

@ বোকম্যাকডোনাগ, আমার অভিজ্ঞতা হ'ল যে বিকাশকারীরা নতুন বিমূর্ততা সম্পর্কে পরিচিত হওয়ার জন্য বিরক্ত করেননি তাদের পক্ষে এটি কম পাঠযোগ্য। আমি আরও পরিচিত হওয়ার জন্য এই জাতীয় এপিআইগুলিকে আরও বেশি ব্যবহার করার পরামর্শ দেব, কারণ এটি ভবিষ্যত। শুধু জাভা বিশ্বে নয়।
luboskrnac

16

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


13

যদি কিছু হয় তবে এটি পড়া এবং বোঝা শক্ত।

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

যদি কিছু হয় তবে এটি পরিচিতির বিষয়।


6
হ্যা ওটা সত্য. তবে এটি আমার কাছে উত্তরের চেয়ে কমেন্টের মতো মনে হচ্ছে।
ওমেগা

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