জাভা অপরিহার্য সংগ্রহ


115

থেকে জাভা 1.6 সংগ্রহ ফ্রেমওয়ার্ক ডকুমেন্টেশন :

যে সংগ্রহগুলি কোনো পরিবর্তন অপারেশন (যেমন সমর্থন করি না add, removeএবং clear) হিসেবে উল্লেখ করা হয় unmodifiable । [...] যে সংগ্রহগুলি অতিরিক্ত গ্যারান্টি দেয় যে সংগ্রহ অবজেক্টে কোনও পরিবর্তন কখনও দৃশ্যমান হবে না তা অপরিবর্তনীয় বলে উল্লেখ করা হয় ।

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

দ্বিতীয় প্রশ্ন:
সংগ্রহটি অপরিবর্তনীয় হওয়ার জন্য, কীভাবে নির্দিষ্ট অতিরিক্ত গ্যারান্টি সরবরাহ করা যায়? সংগ্রহের কোনও উপাদানের অবস্থা যদি কোনও থ্রেড দ্বারা আপডেট করা হয়, তবে কি অপরিবর্তনীয়তার পক্ষে যথেষ্ট যে রাজ্যে থাকা সেই আপডেটগুলি অপরিবর্তনীয় সংগ্রহে থাকা থ্রেডটিতে দৃশ্যমান নয়?

সংগ্রহটি অপরিবর্তনীয় হওয়ার জন্য, কীভাবে নির্দিষ্ট অতিরিক্ত গ্যারান্টি সরবরাহ করা যায়?


সাধারণভাবে (বিশেষত ক্রিয়ামূলক ভাষায়), পরিবর্তনযোগ্য (ওরফে অবিচলিত) সংগ্রহ এই অর্থে পরিবর্তিত হতে পারে যে আপনি এই সংগ্রহের নতুন রাজ্য পেতে পারেন, তবে একই সময়ে পুরানো রাষ্ট্রটি এখনও অন্য লিঙ্কগুলি থেকে উপলব্ধ থাকবে। উদাহরণস্বরূপ, আরও newCol = oldCol.add("element")নতুন উপাদান তৈরি করা হবে যা আরও 1 টি উপাদান সহ পুরানোটির অনুলিপি রয়েছে এবং উইলের সমস্ত উল্লেখ oldColএখনও একই অপরিবর্তিত পুরানো সংগ্রহকে নির্দেশ করবে।
বন্ধু

উত্তর:


154

অপরিবর্তিতযোগ্য সংগ্রহগুলি সাধারণত অন্যান্য সংগ্রহের পঠনযোগ্য কেবলমাত্র দর্শন (মোড়ক)। আপনি এগুলি যোগ করতে, অপসারণ করতে বা সাফ করতে পারবেন না, তবে অন্তর্নিহিত সংগ্রহটি পরিবর্তন করতে পারে।

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

পেয়ারার একটি উদ্ধৃতি এখানে ImmutableList

Collections.unmodifiableList(java.util.List<? extends T>)পৃথক সংগ্রহের দৃশ্য যা এখনও পরিবর্তন করতে পারে ImmutableListতার বিপরীতে , এর উদাহরণটিতে নিজস্ব ব্যক্তিগত ডেটা রয়েছে এবং এটি কখনই পরিবর্তিত হবে না।

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


@ ভাস্কর - আমার শেষ অনুচ্ছেদটি দেখুন।
বোঝো

1
যে সংগ্রহটি অন্য অপরিবর্তনীয় সংগ্রহের অভ্যন্তরে আবৃত থাকে তাতে যদি এর সাথে অন্য কোনও উল্লেখ না থাকে, তবে অবিচ্ছেদ্য সংস্থার বাহাভিউর কি এক অপরিবর্তনীয় সংগ্রহের মতো?
ভাস্কর

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

@ ক্যাক্স: যখন কোনও সংগ্রহ মোড়ানো হয় unmodifiableList, কেবলমাত্র সেই তালিকার রেফারেন্স প্রাপ্ত কোডটি তা সংশোধন করতে সক্ষম হবে না, তবে যে কোডটিতে মূল তালিকার রেফারেন্স ছিল এবং এটি মোড়ক তৈরির আগে এটি সংশোধন করতে পারে তা এখনও থাকবে পরে এটি করতে সক্ষম হবেন। কোডটি যদি মূল তালিকা তৈরি করে থাকে তবে যদি এটি জানত যে এর আগে বিদ্যমান প্রতিটি রেফারেন্সের কী হয়েছে, এবং জানে যে তাদের মধ্যে কোনওটিই কোডের হাতে পড়বে না যে তালিকাটি পরিবর্তন করতে পারে, তবে এটি জানতে পারে যে তালিকা কখনই থাকবে না রুপান্তরিত করা হয়েছে। বাইরের কোড থেকে যদি রেফারেন্স পাওয়া যায়, তবে ...
সুপারক্যাট

... unmodifiableListমোড়ানো সংগ্রহ কীভাবে পরিবর্তন হতে পারে বা কীভাবে তা জানতে পারে না, বা এটি ব্যবহার করে এমন কোনও কোডের কোনও উপায় নেই ।
সুপারক্যাট

86

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

যেমন

List<String> strings = new ArrayList<String>();
List<String> unmodifiable = Collections.unmodifiableList(strings);
unmodifiable.add("New string"); // will fail at runtime
strings.add("Aha!"); // will succeed
System.out.println(unmodifiable);

1
মূল কারণ উল্লেখটি অন্তর্নিহিত সংগ্রহটি সংশোধন করার জন্য ব্যবহার না করা হয় তবে বিভিন্ন কারণগুলি, যদি কোনও, কোনও সংশোধনযোগ্য নয় এমন কোনও সংকলন পরিবর্তন করতে পারে?
ভাস্কর

21
Collection<String> c1 = new ArrayList<String>();
c1.add("foo");
Collection<String> c2 = Collections.unmodifiableList(c1);

c1হয় চপল (অর্থাত তন্ন তন্ন unmodifiable কিংবা অপরিবর্তনীয় )।
c2হয় unmodifiable : এটা নিজেই পরিবর্তন করা যাবে না, কিন্তু পরে যদি আমি পরিবর্তন c1তারপর যে পরিবর্তন দৃশ্যমান হবে c2

এটি c2কেবল চারপাশে মোড়ক c1এবং সত্যিকারের কোনও অনুলিপি নয়। পেয়ারা ImmutableListইন্টারফেস এবং কিছু বাস্তবায়ন সরবরাহ করে। যারা প্রকৃতপক্ষে ইনপুটটির অনুলিপি তৈরি করে কাজ করে (যদি না ইনপুটটি নিজে থেকে একটি পরিবর্তনীয় সংগ্রহ না হয়)।

আপনার দ্বিতীয় প্রশ্ন সম্পর্কে:

কোনও সংগ্রহের অপরিবর্তনীয়তা / অপরিবর্তনীয়তা এতে অন্তর্ভুক্ত বস্তুর পরিবর্তন বা অপরিবর্তনীয়তার উপর নির্ভর করে না । সংগ্রহে থাকা কোনও বস্তুর সংশোধন করা এই বিবরণটির জন্য "সংগ্রহের সংশোধন" হিসাবে গণ্য হয় না । অবশ্যই যদি আপনার এক অপরিবর্তনীয় সংগ্রহের প্রয়োজন হয় তবে আপনি সাধারণত এটিতেও চান যে এটি অপরিবর্তনীয় জিনিস থাকতে পারে।


2
@ জন: না, তা নয়। কমপক্ষে ওপি দ্বারা উদ্ধৃত সংজ্ঞা অনুযায়ী নয়।
জোছিম সউর

@ জনভিন্ট, সত্যিই? আমি এটি ভাবব না, কারণ সি 1 ব্যবহার করে, আমি এখনও এর মধ্যে উপাদানগুলি যুক্ত করতে পারি, এবং এই সংযোজনটি সি 2-তে দৃশ্যমান হবে। তার মানে কি এটি অপরিবর্তনীয় নয়?
ভাস্কর

আমি অনুমান করি যে সি 1 যদি পালাতে পারে তবে তা স্থাবর হতে পারে না, তবে স্থাবরতা সংগ্রহের মধ্যে থাকা সামগ্রীকেও বোঝায়। আমি java.util.Date এর একটি অবিশ্বাস্য সংকলন উল্লেখ করছি
জন ভিন্ট

1
@ ভিন্ট: "যদি c1পালাতে না পারে" এই বিবেচনার বিষয় নয় যা নির্দিষ্টকরণের যে কোনও জায়গায় আলাদা করা যায়। আমার মতে, আপনি যদি সংগ্রহটি এমনভাবে ব্যবহার করতে পারেন যা এটিকে অনির্বচনীয় করে তোলে, তবে আপনার সর্বদা এটি অ-পরিবর্তনীয় বিবেচনা করা উচিত ।
জোচিম সউর

1
আমি সংজ্ঞাটি উদ্ধৃত করি: "সংগ্রহগুলি যা অতিরিক্ত গ্যারান্টি দেয় ..." (জোর দেওয়া খনি)। Collection.unmodifiableList() এটি গ্যারান্টি দিতে পারে না , কারণ এটি গ্যারান্টি দিতে পারে না যে তার যুক্তি এড়াতে পারে না। পেয়ারা ImmutableList.of সর্বদা একটি অপরিবর্তনীয় উত্পাদন করে List, এমনকি যদি আপনি এর যুক্তিগুলি এড়িয়ে যেতে দেন।
জোচিম সৌর

17

এখন জাভা 9 এর অপরিবর্তনীয় তালিকা, সেট, মানচিত্র এবং মানচিত্রের জন্য কারখানা পদ্ধতি রয়েছে nt

জাভা এসই 8 এবং এর আগের সংস্করণগুলিতে আমরা অনাগ্রহী সংগ্রহের অবজেক্ট তৈরির জন্য কালেকশন ক্লাসের ইউটিলিটি পদ্ধতিগুলি যেমন অবিচ্ছেদ্য এক্সএক্সএক্সএক্স ব্যবহার করতে পারি।

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

এখন জাভা 9 তে: - তালিকা এবং সেট ইন্টারফেসের একটি (খালি) শূন্য বা খালি খালি অপরিবর্তনীয় তালিকা তৈরি করতে বা নীচে প্রদর্শিত হবে সেভাবে অবজেক্টগুলি সেট করার পদ্ধতি রয়েছে:

খালি তালিকার উদাহরণ

List immutableList = List.of();

খালি খালি তালিকার উদাহরণ

List immutableList = List.of("one","two","three");

2
এবং জাভা 10 List.copyOfএবং Set.copyOfযুক্ত করা হয়েছে যা একটি তালিকা / সেট একজন unmodifiable অনুলিপি তৈরি করার অনুমতি, অথবা প্রদত্ত সংগ্রহে এটি ইতিমধ্যেই unmodifiable হয় ফিরে দেখতে JDK-8191517
Marcono1234

6

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

অপরিবর্তনীয়, মানে কোনওভাবেই সংগ্রহটি পরিবর্তন করা যায় না।

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


ভাল একটা!! সুতরাং আমি যদি আনমোডিফাইযোগ্য সংগ্রহের উপরে একটি মোড়ক তৈরি করি এবং ব্যক্তিগত হিসাবে পরিবর্তিতযোগ্য সংগ্রহের রেফারেন্স তৈরি করি তবে আমি নিশ্চিত হতে পারি যে এটি অপরিবর্তনীয়। ঠিক আছে?
একেএস

আমি যদি আপনার প্রশ্নটি বুঝতে পারি তবে উত্তরটি হ'ল না। সংশোধনযোগ্যকে মোড়ানো এটিকে সংগ্রহটি unmodifiableListসংশোধন করে দেওয়া থেকে রক্ষা করতে কিছুই করে না । আপনি যদি এই ব্যবহার করতে চান ImmutableList
জন বি

0

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

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

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

দাবি অস্বীকার: আমি এর বিকাশকারী

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