আমি কি কোনও সংগ্রহ বা একটি স্ট্রিম ফিরিয়ে দেব?


163

ধরুন আমার কাছে এমন একটি পদ্ধতি রয়েছে যা একটি সদস্য তালিকায় কেবল পঠনযোগ্য দর্শনকে ফিরিয়ে দেয়:

class Team {
    private List < Player > players = new ArrayList < > ();

    // ...

    public List < Player > getPlayers() {
        return Collections.unmodifiableList(players);
    }
}

আরও ধরুন যে সমস্ত ক্লায়েন্ট তাৎক্ষণিকভাবে তালিকার উপরে একবারে পুনরাবৃত্তি করে। খেলোয়াড়দের একটি জেএললিস্ট বা অন্য কিছুতে রাখতে পারে Maybe ক্লায়েন্ট পরে পরিদর্শন জন্য তালিকার একটি রেফারেন্স সঞ্চয় করে না !

এই সাধারণ দৃশ্যের পরিপ্রেক্ষিতে, আমি কি পরিবর্তে কোনও প্রবাহ ফিরিয়ে আনব?

public Stream < Player > getPlayers() {
    return players.stream();
}

বা জাভাতে অ-প্রতিমাসূচক একটি স্ট্রিম ফিরিয়ে দিচ্ছেন? যে স্ট্রিমগুলি সেগুলিতে তৈরি হয়েছিল একই অভিব্যক্তির ভিতরে সর্বদা "সমাপ্ত" হওয়ার জন্য ডিজাইন করা হয়েছিল?


12
প্রবাদ হিসাবে অবশ্যই এতে কোনও ভুল নেই। সর্বোপরি, players.stream()ঠিক এমন একটি পদ্ধতি যা কলারকে একটি স্ট্রিম ফিরিয়ে দেয়। আসল প্রশ্নটি হ'ল, আপনি কি সত্যই কলারকে একক ট্র্যাভারসাল থেকে সীমাবদ্ধ রাখতে চান, এবং Collectionএপিআইয়ের মাধ্যমে তাকে আপনার সংগ্রহে অ্যাক্সেসও অস্বীকার করতে চান ? সম্ভবত কলার addAllএটির অন্য কোনও সংগ্রহে যেতে চান ?
মার্কো তোপোলনিক

2
এটা সব নির্ভর করে. আপনি সর্বদা সংগ্রহ.ধারা () পাশাপাশি স্ট্রিমাকলেক্ট () করতে পারেন। সুতরাং এটি আপনার এবং কলকারী যারা এই ফাংশনটি ব্যবহার করে তাদের উপর নির্ভর করে।
রাজা আনবাজগান

উত্তর:


222

উত্তরটি বরাবরের মতো, "এটি নির্ভর করে"। এটি কতটা ফিরে আসবে তা নির্ভর করবে। এটি সময়ের সাথে ফলাফল পরিবর্তন হয় কিনা এবং ফিরে আসা ফলাফলের ধারাবাহিকতা কতটা গুরুত্বপূর্ণ তা নির্ভর করে। এবং ব্যবহারকারী কীভাবে উত্তরটি ব্যবহার করতে পারে তার উপর এটি অনেকটাই নির্ভর করে।

প্রথমে নোট করুন যে আপনি সর্বদা একটি স্ট্রিমের থেকে সংগ্রহ পেতে পারেন এবং বিপরীতে:

// If API returns Collection, convert with stream()
getFoo().stream()...

// If API returns Stream, use collect()
Collection<T> c = getFooStream().collect(toList());

সুতরাং প্রশ্নটি হল, যা আপনার কলকারীদের পক্ষে বেশি কার্যকর।

যদি আপনার ফলাফল অসীম হতে পারে তবে কেবল একটি পছন্দ আছে: স্ট্রিম।

যদি আপনার ফলাফলটি খুব বড় হতে পারে তবে আপনি সম্ভবত স্ট্রিমটিকে পছন্দ করেন, যেহেতু এগুলি একবারে বাস্তবায়িত করার কোনও মূল্য থাকতে পারে না এবং এটি করার ফলে গুরুত্বপূর্ণ গাদা চাপ তৈরি হতে পারে।

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

এমনকি যদি আপনি জানেন যে ব্যবহারকারী এটি একাধিকবার পুনরাবৃত্তি করতে পারে বা অন্যথায় এটি রাখে তবে আপনি তার পরিবর্তে কোনও স্ট্রিম ফিরে আসতে চাইতে পারেন, সাধারণ কারণে আপনি যে সংগ্রহটি এটিতে নির্বাচিত করেন তা (যেমন, অ্যারেলিস্ট) নাও থাকতে পারে তারা চান ফর্ম, এবং তারপরে কলকারীকে এটিকে যাইহোক অনুলিপি করতে হবে। আপনি যদি কোনও স্ট্রিম ফিরিয়ে দেন তবে তারা তা করতে পারে collect(toCollection(factory))এবং তারা যা চায় ঠিক তেমন আকারে পেতে পারে।

উপরোক্ত "স্ট্রিমকে প্রাধান্য দিন" মামলাগুলি বেশিরভাগ ক্ষেত্রে স্ট্রিমটি আরও নমনীয় হয় তা থেকে উদ্ভূত হয়; আপনি কীভাবে এটি সংগ্রহে ব্যয় করতে ব্যয় এবং সীমাবদ্ধতা ব্যয় না করে কীভাবে এটি ব্যবহার করতে পারেন তা স্থির করে আবদ্ধ করতে পারেন।

দৃ case় ধারাবাহিকতা প্রয়োজনীয়তার ক্ষেত্রে আপনার যখন সংগ্রহ সংগ্রহ করতে হবে তখন একটি ক্ষেত্রে হ'ল এবং আপনাকে চলমান লক্ষ্যটির ধারাবাহিক স্ন্যাপশট তৈরি করতে হবে। তারপরে, আপনি উপাদানগুলি এমন কোনও সংগ্রহের মধ্যে রাখতে চান যা পরিবর্তিত হবে না।

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


6
যেমনটি আমি বলেছিলাম, কয়েকটি ঘটনা রয়েছে যেখানে এটি উড়ে যায় না, যেমন আপনি যখন চলন্ত টার্গেটের সময় স্ন্যাপশট ফিরিয়ে দিতে চান, বিশেষত যখন আপনার দৃ strong় ধারাবাহিকতার প্রয়োজনীয়তা থাকে। তবে বেশিরভাগ সময়, স্ট্রিমটিকে আরও সাধারণ পছন্দ বলে মনে হয়, যদি না আপনি কীভাবে এটি ব্যবহার করবেন সে সম্পর্কে সুনির্দিষ্ট কিছু না জানেন।
ব্রায়ান গয়েটজ

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

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

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

4
@ মারকো টপলনিক আমি মনে করি না আমরা আমাদের সাথে একমত নই, আপনি সম্ভবত আমাদের প্রচেষ্টা কিছুটা আলাদাভাবে ফোকাস করতে পছন্দ করে থাকতে পারেন except (আমরা এটিতে অভ্যস্ত; সমস্ত মানুষকে খুশি করতে পারি না)) স্ট্রিমির নকশাকেন্দ্রটি মেমরির ডেটা স্ট্রাকচারগুলিতে ফোকাস করে; আরএক্সজাবার জন্য নকশা কেন্দ্রটি বাহ্যিকভাবে উত্পন্ন ইভেন্টগুলিতে আলোকপাত করে। দুটোই ভাল লাইব্রেরি; আপনি যখন তাদের নকশা কেন্দ্রের বাইরে কেসগুলিতে প্রয়োগ করার চেষ্টা করেন তখন উভয়ই খুব ভাল ভাড়া পান না। তবে কেবল একটি হাতুড়ি নিডপয়েন্টের জন্য একটি ভয়ানক হাতিয়ার, এটি হাতুড়িতে কোনও সমস্যা আছে বলে বোঝায় না।
ব্রায়ান গয়েটজ

63

ব্রায়ান গয়েটসের দুর্দান্ত উত্তরটি যুক্ত করার জন্য আমার কাছে কয়েকটি পয়েন্ট রয়েছে ।

"গেটর" স্টাইলের পদ্ধতি কল থেকে কোনও স্ট্রিম ফিরে আসা বেশ সাধারণ। দেখুন স্ট্রিম ব্যবহার পৃষ্ঠা "পদ্ধতি ... যেটা ফিরতি স্ট্রিম" ছাড়া অন্য প্যাকেজের জন্য জাভা 8 javadoc এবং চেহারা java.util.Stream। এই পদ্ধতিগুলি সাধারণত এমন ক্লাসগুলিতে থাকে যেগুলি কোনও কিছুর একাধিক মান বা সংহততা উপস্থাপন করে বা ধারণ করতে পারে। এই জাতীয় ক্ষেত্রে, API গুলি সাধারণত তাদের সংগ্রহ বা অ্যারে ফিরিয়ে দেয়। ব্রায়ান তার উত্তরে যে সমস্ত কারণ উল্লেখ করেছে, সে জন্য এখানে স্ট্রিম-রিটার্নিং পদ্ধতি যুক্ত করা খুব নমনীয়। এই শ্রেণীর অনেকেরই ইতিমধ্যে সংগ্রহ- বা অ্যারে-রিটার্নিং পদ্ধতি রয়েছে, কারণ ক্লাসগুলি স্ট্রিমস এপিআইয়ের পূর্বসূরি রয়েছে। যদি আপনি একটি নতুন এপিআই ডিজাইন করেন, এবং স্ট্রিম-রিটার্নিং পদ্ধতিগুলি সরবরাহ করাটি বোধগম্য হয় তবে সংগ্রহ-ফেরত পদ্ধতিগুলি যুক্ত করার প্রয়োজনও নাও হতে পারে।

ব্রায়ান মানগুলিকে একটি সংকলনে "বাস্তবায়ন" করার ব্যয়ের কথা উল্লেখ করেছিলেন। এই পয়েন্টটি প্রশস্ত করতে, এখানে দুটি ব্যয় এখানে রয়েছে: সংগ্রহের মূল্য সংরক্ষণের জন্য মূল্য (মেমরি বরাদ্দকরণ এবং অনুলিপি) এবং মানগুলি প্রথম স্থানে তৈরি করার জন্য ব্যয়। স্ট্রিমের অলসতা-সন্ধানী আচরণের সুবিধা গ্রহণ করে পরবর্তী খরচটি প্রায়শই হ্রাস বা এড়ানো যায়। এর ভাল উদাহরণ হ'ল এপিআই java.nio.file.Files:

static Stream<String>  lines(path)
static List<String>    readAllLines(path)

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

try (Stream<String> lines = Files.lines(path)) {
    List<String> firstTen = lines.limit(10).collect(toList());
}

কলার যদি স্ট্রিমটি কেবল কোনও প্যাটার্নের সাথে মিলে যাওয়া লাইনে ফিরে আসে তবে অবশ্যই যথেষ্ট মেমরির স্থান সংরক্ষণ করা যায় if

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

Stream<Attribute>  attributes();
Stream<Element>    elements();

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

1
আমি সেই নামকরণের প্রতিমা সম্পর্কে খুব আগ্রহী
নির্বাচন করুন

5
@ জোশুয়া গোল্ডবার্গ জেডিকে এই নামকরণের প্রতিমাটি গ্রহণ করেছে বলে মনে হচ্ছে যদিও এটি একচেটিয়াভাবে নয়। বিবেচনা করুন: CharSequence.chars () এবং .codePPoint (), BufferedReader.lines (), এবং ফাইল.লাইনস () জাভা ৮-তে বিদ্যমান, জাভা 9-তে নিম্নলিখিতগুলি যুক্ত করা হয়েছে: প্রসেস.চিল্ডেন (), নেটওয়ার্কইন্টারফেস.এড্রেসস ( ), স্ক্যানার.টোকেনস (), ম্যাচার.সেল্টস (), জাভা.এক্সএমএল.এইচ.এল.এল.গ্র্যাটোগ্যাট.ক্যাটেলোগগুলি ()। অন্যান্য স্ট্রিম-রিটার্নিং পদ্ধতি যুক্ত করা হয়েছে যা এই আইডিয়ামটি ব্যবহার করবেন না - স্ক্যানার.ফাইন্ডএল () মনে আসে - তবে বহুবচন বিশেষ্য আইডিয়ামটি জেডিকে ন্যায্য ব্যবহারে এসেছে বলে মনে হয়।
স্টুয়ার্ট

1

যে স্ট্রিমগুলি সেগুলিতে তৈরি হয়েছিল একই অভিব্যক্তির ভিতরে সর্বদা "সমাপ্ত" হওয়ার জন্য ডিজাইন করা হয়েছিল?

এগুলি বেশিরভাগ উদাহরণে ব্যবহার করা হয়।

দ্রষ্টব্য: কোনও স্ট্রিম ফিরিয়ে দেওয়া কোনও ইটারেটর ফিরিয়ে দেওয়ার চেয়ে আলাদা নয় (অনেক বেশি উদ্বেগপূর্ণ শক্তি দিয়ে স্বীকৃত)

আইএমএইচও সবচেয়ে ভাল সমাধান হ'ল আপনি কেন এটি করছেন তা সজ্জিত করা এবং সংগ্রহটি ফেরত দেওয়া নয়।

যেমন

public int playerCount();
public Player player(int n);

বা যদি আপনি এগুলি গণনা করতে চান

public int countPlayersWho(Predicate<? super Player> test);

2
এই উত্তরের সমস্যাটি হ'ল ক্লায়েন্টটি ক্লায়েন্টের পদ্ধতিগুলির সংখ্যা বাড়িয়ে তুলতে পারে এমন প্রতিটি ক্রিয়াটি ক্লায়েন্টটি করতে চায় এমন প্রতিটি ক্রিয়াকলাপের পূর্বেই অনুমান করা দরকার।
dkatzel

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

1

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

এখন, সম্ভবত এটিই এমন একটি লক্ষণ যা আপনার চেক করা ব্যতিক্রমগুলির দরকার নেই, যা ন্যায্য, তবে কখনও কখনও সেগুলি অনিবার্য।


1

সংগ্রহগুলির বিপরীতে, স্ট্রিমগুলির অতিরিক্ত বৈশিষ্ট্য রয়েছে । যে কোনও পদ্ধতিতে ফেরানো একটি স্ট্রিম হতে পারে:

  • সীমাবদ্ধ বা অসীম
  • সমান্তরাল বা অনুক্রমিক (একটি ডিফল্ট বিশ্বব্যাপী ভাগ করা থ্রেডপুল যা কোনও অ্যাপ্লিকেশনের অন্য কোনও অংশকে প্রভাবিত করতে পারে) সহ
  • আদেশযুক্ত বা অ-অর্ডারযুক্ত

এই পার্থক্যগুলি সংগ্রহগুলিতেও বিদ্যমান, তবে সেখানে সেগুলি সুস্পষ্ট চুক্তির একটি অংশ:

  • সমস্ত সংকলনের আকার রয়েছে, আইট্রেটার / আইটারেবল অসীম হতে পারে।
  • সংগ্রহগুলি সুস্পষ্টভাবে আদেশ বা অ-অর্ডারযুক্ত
  • সমান্তরালতা ধন্যবাদ থ্রেড-সুরক্ষা ছাড়াই সংগ্রহের যত্নের কিছু নয়।

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

  • (সীমাবদ্ধ, আদেশযুক্ত, অনুক্রমিক)
  • (সীমাবদ্ধ, আদেশযুক্ত, সমান্তরাল)
  • (সসীম, অ-অর্ডারযুক্ত, অনুক্রমিক) ...

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

এটি স্ট্রিমটিকে কেবল কোনও পদ্ধতি স্বাক্ষরে বৈধ পছন্দ হিসাবে ছেড়ে দেয় যখন উপরের সমস্যাগুলির মধ্যে কোনওটিই নয়, যা খুব কমই ঘটে।

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


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

0

আমি মনে করি এটি আপনার দৃশ্যের উপর নির্ভর করে। হতে পারে, আপনি যদি এটি Teamবাস্তবায়ন করেন Iterable<Player>তবে তা যথেষ্ট।

for (Player player : team) {
    System.out.println(player);
}

বা কার্যকরী শৈলীতে:

team.forEach(System.out::println);

তবে আপনি যদি আরও সম্পূর্ণ এবং সাবলীল এপিআই চান তবে একটি স্ট্রিম ভাল সমাধান হতে পারে।


নোট করুন, ওপি পোস্ট করা কোডে, প্লেয়ারের গণনা প্রায় অকেজো, অনুমান ব্যতীত ('এখন খেলছেন 1034 খেলোয়াড়, শুরু করতে এখানে ক্লিক করুন!') এর কারণ আপনি কোনও পরিবর্তনীয় সংগ্রহের অপরিবর্তনীয় দৃশ্য ফিরে আসছেন , সুতরাং এখন আপনার গণনাটি এখন থেকে তিনটি মাইক্রোসেকেন্ডের সাথে সমান হতে পারে। সুতরাং কোনও সংগ্রহ ফেরত দেওয়ার সময় আপনাকে গণনাতে পৌঁছানোর একটি "সহজ" উপায় দেয় (এবং সত্যই stream.count()এটি বেশ সহজ) তবে এই সংখ্যাটি ডিবাগিং বা অনুমান ব্যতীত অন্য কোনও কিছুর জন্য সত্যই খুব অর্থবহ নয় not
ব্রায়ান গোয়েট

0

আরও কিছু উচ্চ-উত্তরদাতা উত্তরদাতাদের দুর্দান্ত পরামর্শ দেওয়ার পরেও আমি আশ্চর্য হয়েছি যে কেউ এ বিষয়ে যথেষ্ট মন্তব্য করেন নি:

যদি আপনার হাতে ইতিমধ্যে "ম্যাটেরিয়ালাইজড" Collectionইন-হ্যান্ড থাকে (যেমন এটি কলটির আগেই তৈরি করা হয়েছিল - যেমনটি প্রদত্ত উদাহরণের ক্ষেত্রে যেমন এটি সদস্য ক্ষেত্র) তবে এটি এটিকে রূপান্তরিত করার কোনও অর্থ নেই Stream। কলকারী সহজেই তা করতে পারে। অন্যদিকে, যদি কলার ডেটাটিকে তার আসল আকারে গ্রাস করতে চায় তবে আপনি এটিকে একটি রূপান্তরিত Streamকরে মূল কাঠামোর একটি অনুলিপি পুনরায় বাস্তবায়নের জন্য তাদেরকে নিরর্থক কাজ করতে বাধ্য করেন।


-1

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

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


7
এটি সম্পূর্ণরূপে উদ্ধৃত হওয়ার কোনও কারণ আছে? কোন উত্স আছে?
জেরাস

-5

আমার সম্ভবত 2 টি পদ্ধতি থাকবে, একটিতে ফিরে আসার জন্য Collectionএবং একটিতে সংগ্রহ হিসাবে ফিরে আসার Stream

class Team
{
    private List<Player> players = new ArrayList<>();

// ...

    public List<Player> getPlayers()
    {
        return Collections.unmodifiableList(players);
    }

    public Stream<Player> getPlayerStream()
    {
        return players.stream();
    }

}

এটি উভয় বিশ্বের সেরা। ক্লায়েন্ট তারা তালিকা বা স্ট্রিম চান কিনা তা চয়ন করতে পারে এবং কেবলমাত্র একটি স্ট্রিম পাওয়ার জন্য তাদের তালিকার অপরিবর্তনীয় অনুলিপি তৈরি করার অতিরিক্ত বস্তু তৈরি করতে হবে না।

এটি আপনার এপিআইতে কেবল আরও 1 টি পদ্ধতি যুক্ত করে যাতে আপনার খুব বেশি পদ্ধতি না থাকে


1
কারণ তিনি এই দুটি বিকল্পের মধ্যে চয়ন করতে চেয়েছিলেন এবং প্রত্যেকের পক্ষে ভাল-বুদ্ধি জিজ্ঞাসা করেছিলেন। তবুও এটি এই ধারণাগুলি সম্পর্কে আরও ভাল বোঝার জন্য প্রত্যেককে সরবরাহ করে।
লিবার্ট পাইউ পিয়ো

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