জাভাতে একটি মানচিত্রের অগভীর অনুলিপি


106

আমি যেমন এটি বুঝতে পারি, Mapজাভাতে একটি অগভীর অনুলিপি তৈরি করার কয়েকটি উপায় রয়েছে (সম্ভবত অন্যরাও) :

Map<String, Object> data = new HashMap<String, Object>();
Map<String, Object> shallowCopy;

// first way
shallowCopy = new HashMap<String, Object>(data);

// second way
shallowCopy = (Map<String, Object>) ((HashMap<String, Object>) data).clone();

এক উপায়ে অন্য উপায়ে পছন্দ হয়, এবং যদি তাই হয় তবে কেন?

একটি বিষয় উল্লেখযোগ্য যে দ্বিতীয় উপায়টি একটি "চেক না করা কাস্ট" সতর্কতা দেয়। সুতরাং আপনার @SuppressWarnings("unchecked")চারপাশে পেতে আপনাকে যুক্ত করতে হবে যা কিছুটা জ্বালাময়ী (নীচে দেখুন)।

@SuppressWarnings("unchecked")
public Map<String, Object> getDataAsMap() {
    // return a shallow copy of the data map
    return (Map<String, Object>) ((HashMap<String, Object>) data).clone();
}

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

উত্তর:


106

একটি অনুলিপি নির্মাণকারী ব্যবহার করে অনুলিপি করা ভাল better clone()জাভা ভেঙে গেছে (এসও দেখুন: কীভাবে সঠিকভাবে ক্লোন পদ্ধতি ওভাররাইড করবেন? )।

নকশায় জোশ ব্লচ - অনুলিপি বনাম ক্লোনিং

আপনি যদি আমার বইটিতে ক্লোনিং সম্পর্কিত আইটেমটি পড়ে থাকেন, বিশেষত আপনি যদি লাইনের মধ্যে পড়ে থাকেন তবে আপনি বুঝতে পারবেন যে আমি মনে করি cloneগভীরভাবে ভেঙে গেছে। [...] এটি লজ্জাজনক যা Cloneableভেঙে গেছে, তবে এটি ঘটে।

ব্লচ (যিনি উপায়ে সংগ্রহের কাঠামোটি ডিজাইন করেছিলেন এবং প্রয়োগ করেছিলেন) এমনকি আরও বলেছিলেন যে তিনি কেবল clone()"পদ্ধতিটি সরবরাহ করেন কারণ লোকেরা এটি প্রত্যাশা করে" provides তিনি আসলে এটিকে মোটেও ব্যবহার করার পরামর্শ দেন না।


আমি মনে করি আরও আকর্ষণীয় বিতর্ক হ'ল একটি অনুলিপি নির্মাণকারীর অনুলিপি তৈরির চেয়ে ভাল, তবে এটি সম্পূর্ণ আলাদা আলোচনা।


1
হ্যাঁ, এটি আমার বইয়ের অন্যতম প্রিয় অংশ।
পলিজেনুব্রিকেন্টস

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

4
অনুলিপি ব্যবহারকারীর ব্যবহারের জন্য আপনি কীভাবে মানচিত্রের অনুলিপিটি প্রয়োগ করছেন তা জানতে হবে না? অপ্রয়োজনীয় সীমাবদ্ধতার মতো মনে হচ্ছে।
জন-হ্যানসন

"যে তিনি কেবল ক্লোন () পদ্ধতিটি কেবল" সরবরাহ করেন কারণ লোকেরা এটি প্রত্যাশা করে "" - উত্স?
অ্যাডাম পার্কিন

60

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

অন্যদিকে clone()জোশ ব্লচের ব্যাখ্যা অনুসারে পদ্ধতিটি ব্যবহার করা ভাল নয় ।

মানচিত্র ইন্টারফেসের (এবং আপনার প্রশ্নের ক্ষেত্রে, আপনি কীভাবে কোনও মানচিত্র অনুলিপি করতে চান তা নয়, হ্যাশম্যাপ নয়) আপনার মানচিত্র # পুটএল () ব্যবহার করা উচিত :

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

উদাহরণ:

// HashMap here, but it works for every implementation of the Map interface
Map<String, Object> data = new HashMap<String, Object>();
Map<String, Object> shallowCopy = new HashMap<String, Object>();

shallowCopy.putAll(data);

2
তাহলে স্পষ্ট করে বলুন: আপনি যদি জানেন এমন একটি প্রয়োগের অনুলিপি করছেনMap যার একটি অনুলিপি নির্মাণকারীর রয়েছে তখন অনুলিপি নির্মাণকারীর ব্যবহার না করার কোনও কারণ নেই?
অ্যাডাম পার্কিন

2
ঠিক, এবং আপনি এমনকি এটি মনে করতে পারেন অন্য উপায় কাছাকাছি যদি আপনি ব্যবহার putAllআপনি জানেন যে প্রয়োজন হবে না যদি Mapবাস্তবায়ন আপনি ব্যবহার করছেন একটি কপি কন্সট্রাকটর আছে বা নেই। যে কোনও Mapবাস্তবায়নের নিছক অনুলিপি নির্ধারক হ'ল অপ্রয়োজনীয়।
লুকা ফাগিওলি

1
অবশ্যই, যদিও আমি সাধারণত 2-লাইনারের চেয়ে 1-লাইনার পছন্দ করি। ;)
অ্যাডাম পার্কিন

11

মানচিত্রটি প্রয়োগ না করে অনুলিপি করুন:

static final Map shallowCopy(final Map source) throws Exception {
    final Map newMap = source.getClass().newInstance();
    newMap.putAll(source);
    return newMap;
}

3
<K,V>প্রকার সুরক্ষা নিশ্চিত করতে সহায়তার জন্য প্রকারের পরামিতিগুলি যুক্ত করার বিষয়টি বিবেচনা করুন ।
বেরেট

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