জাভা 8 স্ট্রিমগুলিতে প্রক্রিয়াকরণের ক্রম কীভাবে নিশ্চিত করবেন?


148

আমি একটি XMLজাভা বস্তুর ভিতরে তালিকাগুলি প্রক্রিয়া করতে চাই । আমি সমস্ত উপাদানগুলি যাতে পেয়েছি সেগুলি প্রক্রিয়াজাতকরণ নিশ্চিত করতে হবে।

সুতরাং আমি যে sequentialপ্রত্যেকটি streamব্যবহার করি তার জন্য কি আমাকে কল করা উচিত? list.stream().sequential().filter().forEach()

অথবা যতক্ষণ না আমি সমান্তরালতা ব্যবহার করি না কেবল স্রোতটি ব্যবহার করা যথেষ্ট? list.stream().filter().forEach()

উত্তর:


338

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

অর্ডার করা সম্পত্তি সমান্তরাল বনাম ক্রমিকের থেকে পৃথক। যেমন যদি আপনি কল stream()একটি উপর HashSetপ্রবাহ যখন কলিং unordered হতে হবে stream()একটি উপর Listরিটার্ন একটি আদেশ স্ট্রীম। নোট করুন যে আপনি unordered()অর্ডারিং চুক্তিটি মুক্তি দিতে এবং সম্ভাব্য পারফরম্যান্স বাড়ানোর জন্য কল করতে পারেন । একবার স্ট্রিমের কোনও অর্ডার না হয়ে অর্ডারটি পুনরায় স্থাপন করার কোনও উপায় নেই। (একটি অর্ডারহীন স্ট্রিমকে sortedঅর্ডারে পরিণত করার একমাত্র উপায় হ'ল কল করা , তবে, ফলস্বরূপ আদেশটি মূল অর্ডারটি অগত্যা নয়)।

আরও দেখুন "ক্রমানুসার" বিভাগে এর java.util.streamপ্যাকেজ ডকুমেন্টেশন

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

এটি খুব সূক্ষ্ম হতে পারে, উদাহরণস্বরূপ একটি অর্ডারযুক্ত স্ট্রিম তৈরি করে Stream.iterate(T,UnaryOperator)যখন Stream.generate(Supplier)একটি আনর্ডারড স্ট্রিম তৈরি করে । মনে রাখবেন আপনি নামেও আপনার প্রশ্নের একটি সাধারণ ভুল করে না ক্রম বজায় রাখা। আপনি যদি নিশ্চিত গতিতে স্ট্রিমের উপাদানগুলি প্রক্রিয়া করতে চান তবে আপনাকে ব্যবহার করতে হবে ।forEach forEachOrdered

সুতরাং যদি আপনার listপ্রশ্নে আপনার প্রকৃতপক্ষে একটি হয় তবে java.util.Listএর stream()পদ্ধতিটি একটি আদেশযুক্ত স্ট্রিম ফিরিয়ে filterদেবে এবং ক্রম পরিবর্তন করবে না। সুতরাং যদি আপনি কল করেন list.stream().filter() .forEachOrdered(), সমস্ত উপাদান ক্রমানুসারে প্রক্রিয়াজাত করা হবে, যখন list.parallelStream().filter().forEachOrdered()উপাদানগুলির জন্য সমান্তরালভাবে প্রক্রিয়া করা যেতে পারে (উদাহরণস্বরূপ ফিল্টার দ্বারা) তবে টার্মিনাল ক্রিয়াকলাপটি এখনও কল করা হবে (যা স্পষ্টতই সমান্তরাল সম্পাদনের সুবিধা হ্রাস করবে) ।

আপনি যদি উদাহরণস্বরূপ, কোনও অপারেশন ব্যবহার করেন

List<…> result=inputList.parallelStream().map(…).filter(…).collect(Collectors.toList());

সমান্তরাল সম্পাদনা থেকে পুরো ক্রিয়াকলাপটি উপকৃত হতে পারে তবে আপনি সমান্তরাল বা অনুক্রমিক স্ট্রিম ব্যবহার না করেই ফলস্বরূপ তালিকা সর্বদা সঠিক ক্রমে থাকবে।


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

আমি বুঝতে পারি List<>অর্ডার সংরক্ষণ করব, তবে কি হবে Collection<>?
জোশ সি

5
@JoshC। এটি প্রকৃত সংগ্রহের ধরণের উপর নির্ভর করে। Setসাধারণত এটি না, যদি না এটি হয় SortedSetবা LinkedHashSet। কোনও Map( keySet(), entrySet()এবং values()) Mapএর নীতিগুলির উত্তরাধিকারের সংগ্রহের দর্শনগুলি , অর্থাৎ মানচিত্রটি যখন একটি SortedMapবা হয় তখন অর্ডার করা হয় LinkedHashMap। আচরণটি সংগ্রহের স্প্লিট্রেটারের দ্বারা বর্ণিত বৈশিষ্ট্যগুলি দ্বারা নির্ধারিত হয় । এর defaultবাস্তবায়ন বৈশিষ্ট্যটির Collectionপ্রতিবেদন করে না ORDERED, সুতরাং এটি অগ্রাহ্য করা না হলে এটি অর্ডারযুক্ত।
হোলগার

@ হোলজার আমার একটি প্রশ্ন ছিল যা আপনার উত্তরের একটি ছোট্ট অংশের সাথে কিছুটা সম্পর্কিত হতে পারে।
নমন

1
সমান্তরাল স্ট্রিমগুলি ব্যবহার forEachOrderedকরার forEachসময় কেবল তার থেকে পৃথক হওয়া লক্ষণীয় - তবে স্টিমিং পদ্ধতিটি পরিবর্তিত হওয়ার ক্ষেত্রে যখন বিষয়গুলি অর্ডার করে তবে যেভাবেই এটি ব্যবহার করা ভাল অনুশীলন ...
স্টিভ চেম্বারস

0

সংক্ষেপে:

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

আরো বিস্তারিত:

অনুক্রমিক বনাম সমান্তরাল বনাম আনর্ডার্ড:

Javadocs

S sequential()
Returns an equivalent stream that is sequential. May return itself, either because the stream was already sequential, or because the underlying stream state was modified to be sequential.
This is an intermediate operation.
S parallel()
Returns an equivalent stream that is parallel. May return itself, either because the stream was already parallel, or because the underlying stream state was modified to be parallel.
This is an intermediate operation.
S unordered()
Returns an equivalent stream that is unordered. May return itself, either because the stream was already unordered, or because the underlying stream state was modified to be unordered.
This is an intermediate operation.

স্ট্রিম অর্ডারিং:

Javadocs

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

যদি কোনও স্ট্রিমের অর্ডার দেওয়া হয়, তবে বেশিরভাগ অপারেশনগুলি তাদের মুখোমুখি ক্রমের উপাদানগুলিতে কাজ করতে সীমাবদ্ধ থাকে; যদি কোনও স্ট্রিমের উত্স [1, 2, 3] সমেত একটি তালিকা থাকে তবে এক্সিকিউটিভ মানচিত্রের (x -> x * 2) ফলাফল অবশ্যই [2, 4, 6] হতে হবে। যাইহোক, যদি উত্সটির কোনও সংজ্ঞায়িত মোকাবিলার আদেশ না থাকে তবে মানগুলির [2, 4, 6] কোনও ক্রম বৈধ ফলাফল হবে।

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

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

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