আমি জাভাতে জেনেরিক তালিকাটি কীভাবে ক্লোন করব?


155

আমার একটি আছে ArrayList<String>যা আমি তার একটি অনুলিপি দিতে চাই। ArrayListএকটি ক্লোন পদ্ধতি রয়েছে যার নিম্নলিখিত স্বাক্ষর রয়েছে:

public Object clone()

আমি এই পদ্ধতিটি কল করার পরে, আমি কীভাবে ফিরে আসা অবজেক্টটিকে কাস্ট করব ArrayList<String>?


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

ঠিক আছে, আমি বেশিরভাগ সি # করি যেখানে এটি সত্যিই সহজ। আপনি যদি আমাকে এই প্রশ্ন থেকে মন্তব্যগুলি সরাতে চান তবে দয়া করে আমাকে জানান।
এস্পো

1
আপনি মন্তব্য করতে পারেন। আমি মনে করি আমার সম্পাদনাগুলি ব্যাখ্যা করেছে যে আমার কী সমস্যা হচ্ছে।
বিল

2
আপনার মন্তব্যটি ঠিক আছে, যদি কিছুটা ঘনিষ্ঠ হয়। আমি জাভা বিকাশকারীদের। নেট বিকাশকারীদের বোকা মনে হয় যে অনেক হুপ কল্পনা করতে পারেন।
আউটলা প্রোগ্রামার

1
@ অস্কার, তিনি ক্লোন করতে চান, এবং ক্লোন কমান্ডটি ব্যবহার করতে চান না। এটি একরকম নাও হতে পারে এটি ক্লোনটি আসলে ক্লোন করে না। আমি মনে করি এটি এই বিষয়। এটি আসলে একটি জটিল প্রশ্ন is
রাফা

উত্তর:


62
ArrayList newArrayList = (ArrayList) oldArrayList.clone();

43
এটি স্ট্রিংসের জন্য সূক্ষ্মভাবে কাজ করবে (যা প্রশ্নটি জিজ্ঞাসা করেছিল), তবে এটি লক্ষণীয় যে অ্যারেলিস্টক্লোন একটি অগভীর অনুলিপি সম্পাদন করবে, সুতরাং তালিকায় যদি পরিবর্তনীয় বস্তুগুলি থাকত তবে তাদের ক্লোন করা হবে না (এবং একটি পরিবর্তন করে) একটি তালিকার সাথে অন্য তালিকায়
এটিও বদলে যাবে

49
লিগ্যাসি কোড ব্যতীত আপনার কোনও কাঁচা ধরণের ব্যবহার এড়ানো উচিত। আপনি ব্যবহার করা ভাল ArrayList<String> newArrayList = (ArrayList<String>) oldArrayList.clone();
সিডিএমকেয়ে

20
এটি অত্যন্ত খারাপ অ্যারেলিস্টে # ক্লোন পদ্ধতি রয়েছে, তবে তালিকাগুলি নিজেই তা করে না। দীর্ঘশ্বাস.
রজারডপ্যাক

12
সম্পর্কিত নয় তবে এটি করার সময়: বাম-হাতের List<String>পরিবর্তে ব্যবহার ArrayList<String>করুন। সংগ্রহগুলি বেশিরভাগ সময় এইভাবে ব্যবহার করা উচিত।
ক্রিস্টোফ রাউসি

3
আরেলিস্টের সদৃশ করতে আমি এই পদ্ধতিটি ব্যবহার করতে পারিনি। ক্লোন () পদ্ধতিটি স্বীকৃত হয়নি।
জ্যাক

318

আপনি ক্লোন করতে চান কেন? একটি নতুন তালিকা তৈরি করা সাধারণত আরও বোধগম্য হয়।

List<String> strs;
...
List<String> newStrs = new ArrayList<>(strs);

কাজ শেষ.


17
এটি কী ধরণের তালিকা তা আপনি জানেন না। এটি একটি লিঙ্কডলিস্ট, মাইওউন কাস্টমলিস্ট বা অ্যারেলিস্টের একটি সাবক্লাস হতে পারে, সেক্ষেত্রে অ্যারেলিস্ট নতুন করা ভুল ধরণের হবে।
স্টিভ কুও

51
মূল তালিকাটি ব্যবহার করা হয় কোনটি প্রয়োগের যত্ন নেব? নতুন তালিকাটি কোনটি প্রয়োগ করে তা সম্ভবত আমি যত্নশীল।
টম হাটিন - 5:25

12
@ স্টিভ কুও: স্বাক্ষরটির ArrayList(Collection<? extends E> c)অর্থ আপনি যুক্তি হিসাবে কোন ধরণের তালিকা ব্যবহার করেন তা বিবেচ্য নয়।
সিডিএমকেয়ে

3
মানে এটি কোনও গভীর অনুলিপি নয়, তাই না?

4
পছন্দ করেছেন
টম হাটিন -

19

এটির জন্য আমি এই কোডটি ব্যবহার করি:

ArrayList copy = new ArrayList (original.size());
Collections.copy(copy, original);

আশা আপনার জন্য উপকারী


3
এবং কাঁচা প্রকারের ব্যবহার এড়িয়ে চলুন .. সুতরাং ArrayListব্যবহারের পরিবর্তেArrayList<YourObject>
মিলোস্মেন্স

2
docs.oracle.com/javase/8/docs/api/java/util/… কাজ করে না কারণ তালিকার আকারগুলি আলাদা।
এমএলপ্রোগ্রামার-সিআইএম

আপনি কেবল ArrayListকনস্ট্রাক্টরের অনুলিপি ওভারলোড ব্যবহার করবেন না কেন ?
টম হাটিন -

19

জাভা 8 এর সাথে এটি একটি স্ট্রিম দিয়ে ক্লোন করা যেতে পারে।

import static java.util.stream.Collectors.toList;

...

List<AnObject> clone = myList.stream().collect(toList());

<AnObject> xy = নতুন অ্যারেলিস্ট <> (ওল্ডলিস্ট) এর মতো করা যেতে পারে;
মির্জাাক

1
এটি কোনও গভীর অনুলিপি নয়, একটি তালিকার উপাদানগুলির পরিবর্তনগুলি অন্যটিতে দেখা যেতে পারে
ইনচারা

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

যদিও আসলেই এটি একটি ক্লোন নয়, তাই না? এপিআই ডক্স থেকে "তালিকার ধরণ, পরিবর্তন, সিরিয়ালাইজিবিলিটি, বা থ্রেড-সুরক্ষার কোনও গ্যারান্টি নেই"। ইওউ, এর মধ্যে একটিও চাই না। toCollectionএকটি ভাল পছন্দ হতে পারে।
টম হাটিন -

16

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


15

আমি মনে করি সংগ্রহের এপিআই ব্যবহার করে কৌশলটি করা উচিত:

দ্রষ্টব্য : অনুলিপি পদ্ধতিটি রৈখিক সময়ে চলে।

//assume oldList exists and has data in it.
List<String> newList = new ArrayList<String>();
Collections.copy(newList, oldList);

13
কেন কেবল নতুন অ্যারেলিস্ট <স্ট্রিং> (ওল্ডলিস্ট) ব্যবহার করবেন না?
সিডিএমকেয়ে

4
আমি বিশ্বাস করি ডক থেকে এটি কার্যকর হবে না * গন্তব্য তালিকার উত্স তালিকার কমপক্ষে দীর্ঘ হওয়া উচিত। যদি এটি দীর্ঘ হয় তবে গন্তব্য তালিকার বাকী উপাদানগুলি প্রভাবিত হবে না।
গ্রেগ ডোমজান

@ গ্রেগডোমজান এটি নয় যে আমি একমত যে এটিই সেরা উপায়, তবে এটি করার একটি উপায়। আপনার ইস্যুটি ঘুরে দেখার জন্য এটি এর মতোই চাকাযুক্ত: তালিকা <স্ট্রিং> নতুন তালিকা = নতুন অ্যারেলিস্ট <> (ওল্ডলিস্ট.সাইজ ());
nckbrz

1
এটি জাভা 8 এর সাথে সম্পর্কিত কিনা তা নিশ্চিত নয়, তবে আকারটি নির্দিষ্ট করেও, এখনও একটি ব্যতিক্রম পেয়েছেন সূচিপত্র: আউটপুটস অফসেসপশন: গন্তব্য.সাইজ () <সোর্স.সাইজ (): 0 <2 উপর List<MySerializableObject> copyList = new ArrayList<>(mMySerializableObjects.size()); এটি ব্যবহার copyList.addAll(original);করা ভাল বিকল্প বলে মনে হচ্ছে
জিন বো

@ GeneBo এটি আকার নির্দিষ্ট করে না। এটি সক্ষমতা উল্লেখ করছে যা একটি খুব আলাদা জিনিস। রহস্য intযুক্তি আনন্দ । আপনি কেন পুরান হওয়ার পরিবর্তে এই অস্পষ্ট স্থির পদ্ধতিটি ব্যবহার করতে চান তা আমার কোনও ধারণা নেই addAll
টম হাটিন - 21

8

আমি অ্যাডএল ব্যবহার করে ভাল কাজ করে।

ArrayList<String> copy = new ArrayList<String>();
copy.addAll(original);

জেনেরিক সিনট্যাক্সের পরিবর্তে প্রথম বন্ধনী ব্যবহার করা হয়


5
এটি স্ট্রিংসের জন্য কাজ করবে, তবে পরিবর্তনযোগ্য বস্তুর জন্য নয়। আপনি সেগুলিও ক্লোন করতে চাইবেন।
jodonnell

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

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

এটি অ্যারেলিস্ট <স্ট্রিং> বিটিডব্লিউ হওয়া উচিত। এছাড়াও, আপনি সম্ভবত নতুন অ্যারেলিস্ট <স্ট্রিং> (মূল) ব্যবহার করা ভাল কারণ এটি কম লেখা এবং ঠিক তত স্পষ্ট।
সিডিএমকেয়ে

4
শুধু ব্যবহার new ArrayList<String>(original)করবেন না কেন ?
ব্যবহারকারী 102008

6

আপনি যদি এইটি পেতে চান তবে তালিকার সাথে কোনও গিটারটি ফিরিয়ে দিতে সক্ষম হবেন এটি করা ভাল:

ImmutableList.copyOf(list);

4

আপনার মত জেনেরিক ইন্টারফেস ক্লোন java.util.Listকরতে কেবল এটি কাস্ট করা প্রয়োজন। এখানে আপনি একটি উদাহরণ:

List list = new ArrayList();
List list2 = ((List) ( (ArrayList) list).clone());

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

আমি জানি এই উত্তরটি চূড়ান্ত উত্তরের নিকটে, তবে আমার উত্তরটি উত্তর দেয় List- আপনি জেনেরিক পিতামাতার সাথে কাজ করার সময় সেই সমস্ত কীভাবে করবেন -ArrayList


2
আপনি ধরে
নিচ্ছেন

@ জুয়ান কার্লোসডিয়াজ এই প্রশ্নটি জিজ্ঞাসা করবে, এটি অ্যারেলিস্ট সম্পর্কে ছিল, তাই আমি এ্যারলিস্টের পক্ষে উত্তর দিয়েছি :)
আহমেদ হামিদি

2

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


2

এটিও কাজ করা উচিত:

ArrayList<String> orig = new ArrayList<String>();
ArrayList<String> copy = (ArrayList<String>) orig.clone()

2
List<String> shallowClonedList = new ArrayList<>(listOfStrings);

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



1

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

 public static <T extends Object> List<T> clone(List<T> list) {
      try {
           List<T> c = list.getClass().newInstance();
           for(T t: list) {
             T copy = (T) t.getClass().getDeclaredConstructor(t.getclass()).newInstance(t);
             c.add(copy);
           }
           return c;
      } catch(Exception e) {
           throw new RuntimeException("List cloning unsupported",e);
      }
}

Listবাস্তবায়ন শ্রেণীর জনসাধারণের নো-আরগ নির্মাতা রয়েছে এমন কোনও গ্যারান্টি নেই। উদাহরণস্বরূপ, Listএস এর দ্বারা ফিরে আসে Array.asList, List.ofবা List.subListসম্ভবত না।
টম হাটিন - 21
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.