অপরিবর্তনীয় বনাম আনমোডিফাইয়েবল সংগ্রহ


170

থেকে সংগ্রহগুলি ফ্রেমওয়ার্ক সংক্ষিপ্ত বিবরণ :

যে সংগ্রহগুলি পরিমার্জন অপারেশন সমর্থন করে না (যেমন add, removeএবং clear) হিসেবে উল্লেখ করা হয় unmodifiable । সংগ্রহগুলি যেগুলি অমার্জনযোগ্য নয় সেগুলি সংশোধনযোগ্য

যে সংগ্রহগুলি অতিরিক্ত গ্যারান্টি দিই যে কোন পরিবর্তন Collectionবস্তুর দৃশ্যমান হবে হিসেবে উল্লেখ করা হয় অপরিবর্তনীয় । যে সংগ্রহগুলি অপরিবর্তনীয় নয় তারা পরিবর্তনীয়

আমি পার্থক্য বুঝতে পারি না। অপরিবর্তনীয় এবং অপরিবর্তনীয় এখানে
পার্থক্য কি ?

উত্তর:


207

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

একটি অপরিবর্তনীয় সংগ্রহ গ্যারান্টি দেয় যে কোনও কিছুই আর संग्रहকে আর পরিবর্তন করতে পারে না । যদি এটি কোনও পরিবর্তনযোগ্য সংগ্রহ মোড়ানো হয় তবে তা নিশ্চিত করে যে অন্য কোনও কোডের সেই সংশোধনযোগ্য সংগ্রহের অ্যাক্সেস নেই। দ্রষ্টব্য যে সংগ্রহে উল্লেখযোগ্য পদার্থগুলির মধ্যে কোনও কোড পরিবর্তন করতে পারে না, তবে সেগুলি এখনও অবধি পরিবর্তনীয় হতে পারে - একটি অপরিবর্তনীয় সংগ্রহ তৈরি StringBuilderকরে objects বস্তুগুলিকে কোনওভাবে "হিমায়িত" করা হয় না।

মূলত, পার্থক্যটি অন্য কোডগুলি আপনার পিছনের পিছনে সংগ্রহ পরিবর্তন করতে সক্ষম হবে কিনা তা নিয়ে।


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

8
@ হাইরিনমাস: দ্রষ্টব্য যে আমি বলিনি যে কিছুই পরিবর্তন করতে পারে না - আমি বলেছিলাম কিছুই কিছুই সংগ্রহ পরিবর্তন করতে পারে না।
জন স্কিটে

1
ঠিক আছে, এটি ভুলভাবে পড়ে থাকতে পারে;) তবে এটি পরিষ্কার করা ভাল।
হাইরি নমস

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

1
@ সাবাননির্ভর: এটি এমন কোনও কোড পাথ আছে যা এখনও পরিবর্তন করতে পারে কিনা তার উপর নির্ভর করে list। কিছু পরে ফোন করতে পারেন list.add(10)তারপর collযে পরিবর্তন প্রতিফলিত হবে, তাই না, আমি এটা অপরিবর্তনীয় বলব না।
জন স্কিটি

92

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

তবে immutableসংগ্রহটিকে অন্য সংগ্রহের কেবল পাঠ্য অনুলিপি হিসাবে বিবেচনা করা যেতে পারে এবং পরিবর্তন করা যায় না। এই ক্ষেত্রে যখন উত্স সংগ্রহ পরিবর্তন হয়, অপরিবর্তনীয় সংগ্রহ পরিবর্তনগুলি প্রতিফলিত করে না

এই পার্থক্যটি কল্পনা করার জন্য এখানে একটি টেস্টকেস রয়েছে।

@Test
public void testList() {

    List<String> modifiableList = new ArrayList<String>();
    modifiableList.add("a");

    System.out.println("modifiableList:"+modifiableList);
    System.out.println("--");


    //unModifiableList

    assertEquals(1, modifiableList.size());

    List<String> unModifiableList=Collections.unmodifiableList(
                                        modifiableList);

    modifiableList.add("b");

    boolean exceptionThrown=false;
    try {
        unModifiableList.add("b");
        fail("add supported for unModifiableList!!");
    } catch (UnsupportedOperationException e) {
        exceptionThrown=true;
        System.out.println("unModifiableList.add() not supported");
    }
    assertTrue(exceptionThrown);

    System.out.println("modifiableList:"+modifiableList);
    System.out.println("unModifiableList:"+unModifiableList);

    assertEquals(2, modifiableList.size());
    assertEquals(2, unModifiableList.size());
            System.out.println("--");



            //immutableList


    List<String> immutableList=Collections.unmodifiableList(
                            new ArrayList<String>(modifiableList));

    modifiableList.add("c");

    exceptionThrown=false;
    try {
        immutableList.add("c");
        fail("add supported for immutableList!!");
    } catch (UnsupportedOperationException e) {
        exceptionThrown=true;
        System.out.println("immutableList.add() not supported");
    }
    assertTrue(exceptionThrown);


    System.out.println("modifiableList:"+modifiableList);
    System.out.println("unModifiableList:"+unModifiableList);
    System.out.println("immutableList:"+immutableList);
    System.out.println("--");

    assertEquals(3, modifiableList.size());
    assertEquals(3, unModifiableList.size());
    assertEquals(2, immutableList.size());

}

আউটপুট

modifiableList:[a]
--
unModifiableList.add() not supported
modifiableList:[a, b]
unModifiableList:[a, b]
--
immutableList.add() not supported
modifiableList:[a, b, c]
unModifiableList:[a, b, c]
immutableList:[a, b]
--

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

2
@ ক্যাক্স দয়া করে তালিকায় 'সি' যুক্ত হওয়ার পরে শেষ তিনটি তালিকার প্রবেশের ফলাফল দেখুন যখন আকার modifiableListএবং unModifiableListবৃদ্ধি উভয়ই immutableListপরিবর্তিত হয়নি
প্রশান্ত ভাতে

1
উহু! বুঝেছি! :) .. সুতরাং এখানে আপনি মোডিফায়বললিস্টের পরিবর্তনগুলি ব্যবহার করে আনডিমিটেবললিস্টটি সংশোধন করেছেন, তবে ইমট্যুটেবললিস্টটি সংশোধন করা যায় না। তবে একইভাবে আপনি ইম্ম্যটেবললিস্টটিও সংশোধন করতে পারেন, আমার মনে হয় এখানে ক্লায়েন্ট কেবল ইমট্যুয়েটলিস্টের রেফারেন্সের অ্যাক্সেস পাবে, মোডেফাইবেললিস্টের রেফারেন্স, যা ইমট্যুবললিস্ট তৈরি হয়েছে তা ক্লায়েন্টের কাছে প্রকাশিত হবে না। ঠিক আছে?
একেএস

1
হ্যাঁ new ArrayList<String>(modifiableList)অপরিবর্তনীয় তালিকার কোনও রেফারেন্স না থাকায় পরিবর্তন করা যায় না
প্রশান্ত ভাতে

@PrashantBhate হাই, সেখানে কোন রেফারেন্স new ArrayList<String>(modifiableList)কারণ new? ধন্যবাদ।
আনহিলিগ

11

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

ওরাকল এর জাভা কালেকশন র‍্যাপার টিউটোরিয়ালে এই কথাটি বলা হয়েছে (জোর দেওয়া হয়েছে):

নিম্নরূপ অনুসারে অবিচ্ছেদ্য মোড়কের দুটি প্রধান ব্যবহার রয়েছে:

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

3

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

জেডিকে সংগ্রহে.অনোমডিফিকেশনযোগ্য এক্সএক্সএক্সএক্স পদ্ধতি সরবরাহ করে তবে আমাদের মতে, এটি হতে পারে

<...>

  • অদক্ষ: ডেটা স্ট্রাকচারগুলিতে এখনও একযোগে পরিবর্তনের চেক, হ্যাশ টেবিলগুলিতে অতিরিক্ত স্থান ইত্যাদি সহ মিউটিয়েবল সংগ্রহের সমস্ত ওভারহেড রয়েছে still

পারফরম্যান্সের কথা ভেবে, আপনারও বিবেচনায় রাখা উচিত যে একটি অবিচ্ছেদ্য মোড়ক সংগ্রহটি অনুলিপি করে না, যেখানে পেয়ারা এবং এখন জেডিকে 9 + তে যেমন ব্যবহারযোগ্য অপরিবর্তনীয় সংস্করণ হিসাবে List.of(...)প্রকৃতপক্ষে দু'বার অনুলিপি করে!
বেনজ

2

জাভা ™ টিউটোরিয়ালগুলি উদ্ধৃত করতে :

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

  • সংগ্রহটি তৈরি হয়ে গেলে তা অপরিবর্তনীয় করে তোলার জন্য। এই ক্ষেত্রে, ব্যাকিং সংগ্রহের কোনও রেফারেন্স বজায় না রাখাই ভাল অনুশীলন। এটি একেবারে অপরিবর্তনীয়তার গ্যারান্টি দেয়।

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

(জোর আমার)

এটি সত্যিই এটির যোগফল।


1

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

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

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

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


1

জাভা ™ টিউটোরিয়ালগুলি নিম্নলিখিত বলে:

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

সংগ্রহটি তৈরি হয়ে গেলে তা অপরিবর্তনীয় করে তোলার জন্য। এই ক্ষেত্রে, ব্যাকিং সংগ্রহের কোনও রেফারেন্স বজায় না রাখাই ভাল অনুশীলন। এটি একেবারে অপরিবর্তনীয়তার গ্যারান্টি দেয়।

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

আমি মনে করি এটি পার্থক্য বোঝার জন্য যথেষ্ট ভাল ব্যাখ্যা good

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