জাভা 8 কেন অপরিবর্তনীয় সংগ্রহগুলি অন্তর্ভুক্ত করে না?


130

জাভা 8.. কার্যকরী প্রোগ্রামিংয়ের প্রতিবন্ধকতা দূর করার জন্য জাভা দল প্রচুর কাজ করেছে particular বিশেষত, java.util সংগ্রহগুলিতে পরিবর্তনগুলি খুব দ্রুত প্রবাহিত ক্রিয়াকলাপে শৃঙ্খলাবদ্ধকরণের দুর্দান্ত কাজ করে। সংগ্রহের ক্ষেত্রে তারা প্রথম শ্রেণির ফাংশন এবং কার্যকরী পদ্ধতি যুক্ত করে কতটা ভাল কাজ করে তা বিবেচনা করে কেন তারা স্থাবরীন সংগ্রহ বা এমনকি অপরিবর্তনীয় সংগ্রহ ইন্টারফেস সরবরাহ করতে পুরোপুরি ব্যর্থ হয়েছে?

কোনও বিদ্যমান কোড পরিবর্তন না করে, জাভা দলটি যে কোনও সময় পরিবর্তনযোগ্য ইন্টারফেসগুলি যোগ করতে পারে যা পরিবর্তনীয়গুলির মতো একই, "সেট" পদ্ধতিগুলি বিয়োগ করে এবং বিদ্যমান ইন্টারফেসগুলি এগুলি থেকে প্রসারিত করতে পারে:

                  ImmutableIterable
     ____________/       |
    /                    |
Iterable        ImmutableCollection
   |    _______/    /          \   \___________
   |   /           /            \              \
 Collection  ImmutableList  ImmutableSet  ImmutableMap  ...
    \  \  \_________|______________|__________   |
     \  \___________|____________  |          \  |
      \___________  |            \ |           \ |
                  List            Set           Map ...

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

অপরিবর্তনীয় সংগ্রহের জয়:

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

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

কেউ আমাকে এই সম্পর্কে ইতিহাস বা আলোচনার দিকে নির্দেশ করতে পারে? অবশ্যই এটি কোথাও সর্বজনীন।


9
এর সাথে সম্পর্কিত - আয়েন্দে সম্প্রতি সি # তে সংগ্রহ ও অপরিবর্তনীয় সংগ্রহগুলি সম্পর্কে মাপদণ্ডের সাথে ব্লগ করেছেন। ayende.com/blog/tags/performance - tl; dr - অপরিবর্তনশীলতা ধীর
ওডে

20
আপনার শ্রেণিবিন্যাসের সাথে আমি আপনাকে একটি ইমটুটেবললিস্ট দিতে পারি এবং তারপরে এটি পরিবর্তন করতে পারি যখন আপনি এটির প্রত্যাশা করেন না যা অনেক কিছুই ভাঙতে পারে, যেমন আপনার কেবল constসংগ্রহ রয়েছে
ratchet freak

18
@ ওড্ড অপ্রচলতা ধীর, তবে লক করাও। তাই একটি ইতিহাস বজায় রাখা হয়। সরলতা / সঠিকতা অনেক পরিস্থিতিতে গতি মূল্য। ছোট সংগ্রহ সহ, গতি কোনও সমস্যা নয়। আয়েনদীর বিশ্লেষণ এই ধারণাটি ভিত্তিতে তৈরি হয়েছে যে আপনার ইতিহাস, লকিং বা সরলতার প্রয়োজন নেই এবং আপনি একটি বড় ডেটা সেট নিয়ে কাজ করছেন। কখনও কখনও এটি সত্য, তবে এটি সর্বদাই সেরা জিনিস নয়। ট্রেড অফ আছে।
গ্লেনপিটারসন

5
@ গ্লেনপিটারসন এটির Collections.unmodifiable*()জন্য রক্ষণাত্মক অনুলিপি এবং সেগুলি। তবে তারা যখন তা না হয় তখন এগুলিকে অপরিবর্তনীয় হিসাবে গণ্য করবেন না
ratchet freak

13
অঁ্যা? যদি আপনার ফাংশনটি ImmutableListসেই চিত্রটিতে লাগে তবে লোকেরা পরিবর্তন করতে পারে List? না এটি এলএসপির খুব খারাপ লঙ্ঘন।
টেলাস্টিন

উত্তর:


113

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

আরও, অপরিবর্তনীয় সংগ্রহগুলি প্রায়শই তাদের পরিবর্তনীয় অংশগুলির চেয়ে মৌলিকভাবে পৃথক বাস্তবায়ন করে। উদাহরণস্বরূপ বিবেচনা করুন ArrayList, একটি দক্ষ অপরিবর্তনীয় ArrayListকোনও অ্যারে হবে না! এটি একটি বৃহত শাখা ফ্যাক্টর সহ ভারসাম্যযুক্ত গাছের সাথে প্রয়োগ করা উচিত, ক্লোজুরে 32 আইআইআরসি ব্যবহার করে। কেবলমাত্র একটি কার্যকরী আপডেট যুক্ত করে পরিবর্তনীয় সংগ্রহগুলি "অপরিবর্তনীয়" হিসাবে তৈরি করা একটি স্মৃতি মেমরির ফাঁস হওয়ার মতোই পারফরম্যান্স বাগ is

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

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


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

4
আমি আপনার উত্তরটি আবার পড়েছি এবং আমি মনে করি আপনি বলছেন যে জাভাটির পরিবর্তনশীলতার একটি মৌলিক ধারণা রয়েছে (যেমন জাভা মটরশুটি) এবং সংগ্রহগুলি কেবল আইসবার্গের টিপ এবং সেই ডগাটি খোদাই করার ফলে অন্তর্নিহিত সমস্যার সমাধান হবে না। একটি বৈধ পয়েন্ট। আমি এই উত্তরটি গ্রহণ করতে পারি এবং আমার স্কালাকে গ্রহণের গতি বাড়িয়ে দেব! :-)
গ্লেনপিটারসন

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

3
ভাগ করে ভাগ করে জাভাতে এক অপরিবর্তনীয় সংগ্রহ করা সম্পূর্ণভাবে সম্ভব। সংগ্রহে সঞ্চিত আইটেমগুলি রেফারেন্স এবং তাদের রেফারেন্টগুলি রূপান্তরিত হতে পারে - তবে কী? এই জাতীয় আচরণ ইতিমধ্যে হ্যাশম্যাপ এবং ট্রিসেটের মতো বিদ্যমান সংগ্রহগুলি ভেঙে দেয়, তবুও সেগুলি জাভাতে প্রয়োগ করা হয়। এবং যদি একাধিক সংগ্রহে একই অবজেক্টের রেফারেন্স থাকে তবে এটি সম্পূর্ণরূপে প্রত্যাশিত যে অবজেক্টটি সংশোধন করা যখন সমস্ত সংগ্রহ থেকে দেখা হয় তখন পরিবর্তনটি দৃশ্যমান হতে পারে।
সলোমনফের সিক্রেট

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

77

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

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

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

  • একটি অপরিবর্তনীয় সংগ্রহ হ'ল যা সর্বদা একই ডেটা ধরে রাখবে যতক্ষণ না এর কোনও রেফারেন্স বিদ্যমান থাকে। একটি স্থাবর ইন্টারফেসের কোনও প্রয়োগ যা কোনও নির্দিষ্ট অনুরোধের জবাব হিসাবে সর্বদা একই ডেটা ফেরত দেয় না তা ভেঙে যায়।

মাঝে মাঝে অতিমাত্রায় এসোসিয়েটেড চপল এবং অপরিবর্তনীয় সংগ্রহ ধরনের যা উভয় বাস্তবায়ন বা একই "পাঠযোগ্য" টাইপ থেকে আহরণ করা, এবং পাঠযোগ্য প্রকার থাকা অন্তর্ভুক্ত আছে দরকারী AsImmutable, AsMutableএবং AsNewMutableপদ্ধতি। এই জাতীয় নকশা এমন কোনও কোডকে অনুমতি দিতে পারে যা কোনও সংগ্রহে থাকা ডেটা ধরে রাখতে চাইবে কল করতে AsImmutable; সংগ্রহটি পরিবর্তনযোগ্য হলে সেই পদ্ধতিটি একটি প্রতিরক্ষামূলক অনুলিপি তৈরি করবে, তবে অনুলিপিটি যদি এটি ইতিমধ্যে পরিবর্তনযোগ্য হয় তবে এড়িয়ে যান ip


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

1
@ লরেন্টবৌরগোল্ট-রায়: সীলমোহরযুক্ত এবং উত্তরাধিকারসূত্রে উভয় প্রকারের পরিবর্তনযোগ্য সুবিধা রয়েছে। যদি কেউ অবৈধ উদ্ভূত শ্রেণীর আক্রমণকারীদের ভাঙতে দেয় না, সিলযুক্ত প্রকারগুলি তার বিরুদ্ধে সুরক্ষা দিতে পারে তবে উত্তরাধিকার সূত্রে প্রাপ্ত শ্রেণিগুলি কেউই অফার করে না। অন্যদিকে, কোডের পক্ষে এটি সম্ভব যে কোনও তথ্য যা এ সম্পর্কে কিছুই জানে না তার চেয়ে অনেক কমপ্যাক্টভাবে সংরক্ষণ করার জন্য এটি যে ডেটা ধারণ করে তা সম্পর্কে কিছু জানে । উদাহরণস্বরূপ, একটি ReadableIndexedIntSequence টাইপ বিবেচনা করুন যা intপদ্ধতি getLength()এবং সহ একটি ক্রমকে আবদ্ধ করে getItemAt(int)
সুপারক্যাট

1
@ লরেন্টবৌরগোল্ট-রায়: একটি দেওয়া হলে ReadableIndexedIntSequence, সমস্ত আইটেমিকে একটি অ্যারে অনুলিপি করে অ্যারে-ব্যাকড অপরিবর্তনীয় টাইপের একটি উদাহরণ তৈরি করা যেতে পারে তবে মনে করুন যে কোনও নির্দিষ্ট প্রয়োগটি কেবল দৈর্ঘ্যের ((long)index*index)>>24জন্য এবং প্রতিটি আইটেমের জন্য 16777216 ফিরে এসেছে । এটি পূর্ণসংখ্যার বৈধ অপরিবর্তনীয় ক্রম হতে পারে তবে এটিকে একটি অ্যারে অনুলিপি করা সময় এবং স্মৃতির বিশাল অপচয় হবে।
সুপারক্যাট

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

1
@ লরেন্টবৌরগোল্ট-রায়: মৌলিক প্রশ্ন হ'ল কোনও ব্যক্তি ভাঙা বাস্তবায়ন বা উত্সর্গীকৃত শ্রেণি উত্পাদন না করার জন্য লোকদের উপর নির্ভর করে। যদি কেউ এটি করে এবং যদি ইন্টারফেস / বেস ক্লাসগুলি পরিবর্তনযোগ্য / asImmutable পদ্ধতি হিসাবে সরবরাহ করে তবে অনেকগুলি প্রশস্ততার অর্ডার দ্বারা কর্মক্ষমতা উন্নত করা সম্ভব হতে পারে [উদাহরণস্বরূপ asImmutable, বিল্ডিং ব্যয়ের তুলনায় উপরের সংজ্ঞায়িত ক্রমের একটি উদাহরণে কল করার ব্যয়ের তুলনা করুন) একটি অপরিবর্তনযোগ্য অ্যারে-ব্যাকড অনুলিপি]। আমি মনে করব যে এই জাতীয় উদ্দেশ্যে সংজ্ঞাযুক্ত ইন্টারফেসগুলি সম্ভবত অ্যাড-হক পদ্ধতির ব্যবহার করার চেষ্টা করার চেয়ে ভাল; আইএমএইচও, সবচেয়ে বড় কারণ ...
সুপারক্যাট c

15

জাভা কালেকশন ফ্রেমওয়ার্ক জাভা.ইটি.ল.ক্লাকশন ক্লাসে ছয়টি স্ট্যাটিক পদ্ধতির মাধ্যমে একটি সংকলনের কেবল পঠন সংস্করণ তৈরি করার ক্ষমতা সরবরাহ করে :

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

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


4
অনিবার্যযোগ্য সংগ্রহের নকশাটি অনেকাংশে বাড়ানো যেত যদি মোড়কগুলিতে কোনও জিনিস মুড়ে ফেলা হচ্ছে কিনা তা ইতিমধ্যে অপরিবর্তনীয় কিনা এবং এমন কোনও immutableListকারখানার পদ্ধতি ছিল যা কোনও পাস-ইন-অনুলিপিটির চারপাশে কেবল পঠনযোগ্য মোড়কে ফিরে আসত of তালিকা যদি না পাস-ইন তালিকাটি ইতিমধ্যেই অপরিবর্তনীয় ছিল । এর মতো ব্যবহারকারীর দ্বারা সংজ্ঞায়িত প্রকারগুলি তৈরি করা সহজ হবে তবে একটি সমস্যার জন্য: joesCollections.immutableListপদ্ধতির পক্ষে এটি স্বীকৃতি দেওয়ার কোনও উপায় নেই যে এটির দ্বারা প্রত্যাবর্তিত বস্তুটি অনুলিপি করার দরকার নেই fredsCollections.immutableList
সুপারক্যাট

8

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

জাভা প্রোগ্রামারদের একটি শতাংশ শ্রেণীর unmodifiableCollection()পদ্ধতিগুলির পরিবারের অস্তিত্ব সম্পর্কে সচেতন Collections, তবে তাদের মধ্যেও অনেকে এটি নিয়ে বিরক্ত হন না।

এবং আমি তাদের দোষ দিতে পারি না: একটি ইন্টারফেস যা পড়ার লেখার ভান করে তবে UnsupportedOperationExceptionযদি আপনি এর কোনও 'লেখার' পদ্ধতিতে অনুরোধ করার ভুল করেন তবে তা খুব খারাপ জিনিস!

এখন, একটি ইন্টারফেস Collectionযা অনুপস্থিত হবে add(), remove()এবং clear()পদ্ধতি একটি "ImmutableCollection" ইন্টারফেস হবে না; এটি একটি "অপরিবর্তিতযোগ্য সংগ্রহ" ইন্টারফেস হবে। প্রকৃতপক্ষে, কোনও "অপরিবর্তনীয় কালেকশন" ইন্টারফেস হতে পারে না, কারণ অপরিবর্তনীয়তা একটি প্রয়োগের একটি প্রকৃতি, কোনও ইন্টারফেসের বৈশিষ্ট্য নয়। আমি জানি, এটি খুব পরিষ্কার নয়; আমাকে বিস্তারিত বলতে দাও.

মনে করুন যে কেউ আপনাকে এমন একটি পঠনযোগ্য কেবল সংগ্রহ ইন্টারফেস দেয়; এটি অন্য থ্রেডে পৌঁছে দেওয়া কি নিরাপদ? যদি আপনি নিশ্চিতভাবে জানতেন যে এটি সত্যিকারের অপরিবর্তনীয় সংগ্রহের প্রতিনিধিত্ব করে, তবে উত্তরটি "হ্যাঁ" হবে; দুর্ভাগ্যবশত, যেহেতু এটি একটি ইন্টারফেস, আপনি জানেন না কিভাবে এটা বাস্তবায়িত হয়, তাই উত্তর হতে হয়েছে একটি কোন : সমস্ত আপনি কি জানেন, এটি একটি unmodifiable (আপনাকে) একটি সংগ্রহে আছে যা চপল আসলে দৃশ্যে হতে পারে, (আপনি যা পেয়েছেন তা পছন্দ করুন Collections.unmodifiableCollection()) সুতরাং অন্য থ্রেডটি পরিবর্তিত করার সময় এটি থেকে পড়ার চেষ্টা করার ফলে দুর্নীতিগ্রস্থ ডেটা পড়ার ফলস্বরূপ।

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

অপরিবর্তনীয় সংগ্রহগুলি রাখতে তাদের ক্লাস হতে হবে , ইন্টারফেস নয়!

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

সুতরাং, জাভাতে (বা অন্য কোনও ঘোষণামূলক অপরিহার্য ভাষায়) সম্পূর্ণ সংকলনের জন্য আমাদের নিম্নলিখিতগুলির প্রয়োজন হবে:

  1. অমীমাংসিত সংগ্রহের ইন্টারফেসগুলির একটি সেট ।

  2. পরিবর্তনীয় সংগ্রহের ইন্টারফেসগুলির একটি সেট, অবিচ্ছেদ্যযোগ্যগুলি প্রসারিত করে।

  3. একটি সেট চপল সংগ্রহ শ্রেণীর , এবং এক্সটেনশান এছাড়াও unmodifiable ইন্টারফেসগুলি দ্বারা চপল ইন্টারফেসগুলি বাস্তবায়ন।

  4. অপরিবর্তনীয়যোগ্য ইন্টারফেস বাস্তবায়ন করে অপরিবর্তনীয় সংগ্রহের ক্লাসগুলির একটি সেট , তবে বেশিরভাগই ক্লাস হিসাবে প্রায় পাশ করেছে, যাতে অপরিবর্তনীয়তার গ্যারান্টি রয়েছে।

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

তারা জাভা রানটাইমের অংশ না হওয়ার কারণ সম্ভবত এটি ধারণা করা হয়েছিল যে এটি খুব বেশি / খুব জটিল / বুঝতে খুব কঠিন হবে।

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


ভাল দিক. দুটি বিবরণ: ১. অপ্রয়োজনীয় সংগ্রহের জন্য নির্দিষ্ট পদ্ধতি স্বাক্ষর প্রয়োজন, বিশেষত (উদাহরণ হিসাবে একটি তালিকা ব্যবহার করে): List<T> add(T t)- সমস্ত "মিউটর" পদ্ধতির অবশ্যই একটি নতুন সংগ্রহ ফেরত পাঠাতে হবে যা পরিবর্তনের প্রতিফলন ঘটায়। 2. আরও ভাল বা খারাপ জন্য, ইন্টারফেসগুলি প্রায়শই স্বাক্ষর ছাড়াও একটি চুক্তি উপস্থাপন করে । সিরিয়ালাইজেবল এমন একটি ইন্টারফেস। একইভাবে, তুলনীয় আপনি সঠিকভাবে আপনার বাস্তবায়ন প্রয়োজন compareTo()সঠিকভাবে কাজ এবং আদর্শভাবে সঙ্গে সামঞ্জস্যপূর্ণ হতে পদ্ধতি equals()এবং hashCode()
গ্লেনপিটারসন

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

আপনার বাস্তবায়ন কি সর্বজনীনভাবে উপলব্ধ? আমার এই মাস আগে জিজ্ঞাসা করা উচিত ছিল। যাইহোক, আমার হ'ল: github.com/GlenKPeterson/UncleJim
GlenPeterson

4
Suppose someone hands you such a read-only collection interface; is it safe to pass it to another thread?মনে করুন কেউ আপনাকে কোনও পরিবর্তনীয় সংগ্রহের ইন্টারফেসের উদাহরণ দিয়ে যায়। এটিতে কোনও পদ্ধতিতে প্রার্থনা করা কি নিরাপদ? আপনি জানেন না যে বাস্তবায়ন চিরকালের জন্য লুপ করে না, একটি ব্যতিক্রম ছুঁড়ে না, বা ইন্টারফেসের চুক্তিকে সম্পূর্ণ উপেক্ষা করে। কেন পরিবর্তনীয় সংগ্রহের জন্য বিশেষত একটি দ্বৈত মান রয়েছে?
ডোভাল

1
পরিবর্তনীয় ইন্টারফেসের বিরুদ্ধে আপনার যুক্তি IMHO করুন। আপনি পরিবর্তনীয় ইন্টারফেসগুলির একটি পরিবর্তনীয় বাস্তবায়ন লিখতে পারেন এবং তারপরে এটি ভেঙে যায়। অবশ্যই। আপনি চুক্তি লঙ্ঘন করছেন তবে এটি আপনার দোষ। শুধু এটা করা বন্ধ করুন। এটি SortedSetঅ-সঙ্গতিপূর্ণ বাস্তবায়ন দিয়ে সেটটি সাবক্লাসিং করে ভেঙে আলাদা নয় । বা একটি বেমানান পেরিয়ে Comparable। আপনি চাইলে প্রায় কোনও কিছু ভেঙে যেতে পারে। আমার ধারণা, এটিই "ডাবল স্ট্যান্ডার্ড" দ্বারা বোঝানো @ ডোভাল।
মার্টিনাস

2

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

এই সংগ্রহগুলিতে সমস্ত জাভা অবজেক্টের স্বতন্ত্র আইডি না থাকলে বা কিছুটা হ্যাশ বিটস্ট্রিং না থাকলে সংগ্রহের স্বতন্ত্র নামকরণের জন্য হ্যাশের কিছুই নেই।

উদাহরণ: আমার 4x1.6ghz ল্যাপটপে, আমি দীর্ঘতম হ্যাশটেবলের 500K হ্যাশমে্যাপ অপস বা 3 এম অপ্সের তুলনায় 1 হ্যাশ চক্রের (55 বাইট অবধি) মাপসই সবচেয়ে ছোট আকারের 200K sha256s চালাতে পারি। 200 কে / লগ (কালেকশনসাইজ) প্রতি সেকেন্ডে নতুন সংগ্রহগুলি এমন কিছু জিনিসের জন্য যথেষ্ট দ্রুত যেখানে ডেটা অখণ্ডতা এবং বেনামে বিশ্বব্যাপী স্কেলাবিলিটি গুরুত্বপূর্ণ।


-3

কর্মক্ষমতা. তাদের প্রকৃতির দ্বারা সংগ্রহগুলি খুব বড় হতে পারে। একটি একক উপাদান সন্নিবেশ না করে 1001 উপাদান দিয়ে একটি নতুন কাঠামোতে 1000 টি উপাদান অনুলিপি করা কেবল সাধারণ ভয়ঙ্কর।

Concurrency। আপনার যদি বেশ কয়েকটি থ্রেড চলমান থাকে তবে তারা থ্রেড শুরু হওয়ার পরে 12 ঘন্টা আগে পাস করা সংস্করণটি সংগ্রহের বর্তমান সংস্করণটি পেতে চাইবেন।

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


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

4
দম্পতি সমস্যা। ক্লোজার এবং স্কালায় সংগ্রহগুলি উভয়ই অপরিবর্তনীয়, তবে হালকা-ওজনের অনুলিপিগুলিকে সমর্থন করে। 1001 উপাদান যুক্ত করা মানে 33 টিরও কম উপাদানের অনুলিপি করা, আরও কয়েকটি নতুন পয়েন্টার তৈরি করা। আপনি যদি থ্রেড জুড়ে একটি পরিবর্তনীয় সংগ্রহ ভাগ করেন, আপনি যখন এটি পরিবর্তন করেন তখন আপনার কাছে সমস্ত ধরণের সিঙ্ক্রোনাইজেশন সমস্যা থাকে। "রিমুভ ()" এর মতো অপারেশনগুলি দুঃস্বপ্ন। এছাড়াও, পরিবর্তনীয় সংগ্রহগুলি পারস্পরিকভাবে তৈরি করা যেতে পারে, তারপরে একবারে থ্রেডগুলি জুড়ে ভাগ করে নিতে নিরাপদ স্থায়ী সংস্করণে অনুলিপি করা হয়েছে।
গ্লেনপিটারসন

4
অপরিবর্তনীয়তার বিরুদ্ধে যুক্তি হিসাবে একচেটিয়া ব্যবহার করা অস্বাভাবিক। সদৃশ পাশাপাশি।
টম হাটিন -

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

3
@ জেমস অ্যান্ডারসন: আপনার উত্তরের সাথে আমার সমস্যাগুলি: "পারফরম্যান্স" - আপনি বলতে পারেন যে বাস্তব জীবনের অপরিবর্তনীয় সংগ্রহগুলি সর্বদা কিছু ভাগ করে নেওয়ার প্রয়োগ করে এবং আপনার বর্ণিত সমস্যাটি এড়াতে পুনরায় ব্যবহার করুন। "কনক্যুরঞ্জি" - যুক্তিটি "আপনি যদি পরিবর্তন পরিবর্তন করতে চান তবে একটি স্থাবর বস্তুটি কাজ করে না" -এটি উত্সাহিত করে। আমি বোঝাতে চাইছি যদি "একই জিনিসটির সর্বশেষ সংস্করণ" সম্পর্কে ধারণা পাওয়া যায়, তবে কোনও জিনিসটির নিজস্বতা বা জিনিসটির মালিকানাধীন কিছু পরিবর্তন করতে হবে। এবং "স্টোরেজ" এ, আপনি বলে মনে করছেন যে কখনও কখনও পরিবর্তন হ'ল কাঙ্ক্ষিত হয় না।
ঝমিনাল
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.