[Java] ArrayList क्लोन कैसे करें और इसकी सामग्री को क्लोन करें?


Answers

मैं व्यक्तिगत रूप से कुत्ते को एक कन्स्ट्रक्टर जोड़ूंगा:

class Dog
{
    public Dog()
    { ... } // Regular constructor

    public Dog(Dog dog) {
        // Copy all the fields of Dog.
    }
}

फिर बस पुनरावृत्त (जैसा कि वर्खन के उत्तर में दिखाया गया है):

public static List<Dog> cloneList(List<Dog> dogList) {
    List<Dog> clonedList = new ArrayList<Dog>(dogList.size());
    for (Dog dog : dogList) {
        clonedList.add(new Dog(dog));
    }
    return clonedList;
}

मुझे इसका लाभ मिलता है कि आपको जावा में टूटी क्लोनेबल सामान के साथ घूमने की आवश्यकता नहीं है। यह जावा संग्रहों की प्रतिलिपि बनाने के तरीके से भी मेल खाता है।

एक और विकल्प आपके स्वयं के आईसीएलनेबल इंटरफ़ेस को लिखना और इसका उपयोग करना हो सकता है। इस तरह आप क्लोनिंग के लिए एक सामान्य विधि लिख सकते हैं।

Question

मैं एक ArrayList क्लोन कैसे कर सकता हूं और जावा में अपनी वस्तुओं को क्लोन भी कर सकता हूं?

उदाहरण के लिए मेरे पास है:

ArrayList<Dog> dogs = getDogs();
ArrayList<Dog> clonedList = ....something to do with dogs....

और मैं उम्मीद करता हूं कि clonedList में ऑब्जेक्ट्स कुत्तों की सूची में समान नहीं हैं।




आपके लिए क्लोन () विधि ओवरराइड करता है

class You_class {

    int a;

    @Override
    public You_class clone() {
        You_class you_class = new You_class();
        you_class.a = this.a;
        return you_class;
    }
}

और वेक्टर ओबीजे या ArraiList obj के लिए कॉल .clone () ....




पैकेज import org.apache.commons.lang.SerializationUtils;

SerializationUtils.clone(Object); एक विधि है SerializationUtils.clone(Object);

उदाहरण

this.myObjectCloned = SerializationUtils.clone(this.object);



मुझे लगता है कि वर्तमान हरा जवाब बुरा है , आप क्यों पूछ सकते हैं?

  • इसमें बहुत सारे कोड जोड़ने की आवश्यकता हो सकती है
  • यह आपको कॉपी करने के लिए सभी सूची सूचीबद्ध करने और इसे करने की आवश्यकता है

जिस तरह से क्रमबद्धता भी खराब आईएमओ है, आपको पूरे स्थान पर Serializable जोड़ना पड़ सकता है।

तो समाधान क्या है:

जावा डीप-क्लोनिंग लाइब्रेरी क्लोनिंग लाइब्रेरी एक छोटा, खुला स्रोत (अपाचे लाइसेंस) जावा लाइब्रेरी है जो गहरे क्लोन ऑब्जेक्ट्स है। वस्तुओं को क्लोनेबल इंटरफ़ेस को लागू करने की आवश्यकता नहीं है। प्रभावशाली, यह पुस्तकालय किसी भी जावा वस्तुओं को क्लोन कर सकता है। इसका उपयोग कैश कार्यान्वयन में किया जा सकता है यदि आप नहीं चाहते हैं कि कैश किए गए ऑब्जेक्ट को संशोधित किया जाए या जब भी आप ऑब्जेक्ट की गहरी प्रतिलिपि बनाना चाहते हों।

Cloner cloner=new Cloner();
XX clone = cloner.deepClone(someObjectOfTypeXX);

इसे https://github.com/kostaskougios/cloning पर https://github.com/kostaskougios/cloning




जावा 8 तत्व कुत्तों पर कॉपी कन्स्ट्रक्टर या क्लोन विधि को सुंदर और कॉम्पैक्टली पर कॉल करने का एक नया तरीका प्रदान करता है: स्ट्रीम , लैम्बडा और कलेक्टर

कन्स्ट्रक्टर कॉपी करें:

List<Dog> clonedDogs = dogs.stream().map(Dog::new).collect(toList());

अभिव्यक्ति Dog::new एक विधि संदर्भ कहा जाता है। यह Dog पर एक निर्माता का संदर्भ देता है जो तर्क के रूप में एक और कुत्ता लेता है।

क्लोन विधि:

List<Dog> clonedDogs = dogs.stream().map(d -> d.clone()).collect(toList());

परिणाम के रूप में एक ArrayList प्राप्त करना

या, यदि आपको एक ArrayList वापस प्राप्त करना है (यदि आप इसे बाद में संशोधित करना चाहते हैं):

ArrayList<Dog> clonedDogs = dogs.stream().map(Dog::new).collect(toCollection(ArrayList::new));

जगह में सूची अद्यतन करें

यदि आपको dogs सूची की मूल सामग्री रखने की आवश्यकता नहीं है, तो आप replaceAll विधि का उपयोग कर सकते हैं और इसके बजाय सूची को अपडेट कर सकते हैं:

dogs.replaceAll(Dog::new);

सभी उदाहरण import static java.util.stream.Collectors.*;

ArrayList एस के लिए कलेक्टर

अंतिम उदाहरण से संग्राहक को एक उपयोग विधि में बनाया जा सकता है। चूंकि यह एक आम बात है क्योंकि मुझे व्यक्तिगत रूप से इसे छोटा और सुंदर होना पसंद है। इस कदर:

ArrayList<Dog> clonedDogs = dogs.stream().map(d -> d.clone()).collect(toArrayList());

public static <T> Collector<T, ?, ArrayList<T>> toArrayList() {
    return Collectors.toCollection(ArrayList::new);
}

CloneNotSupportedException पर नोट:

इस समाधान के लिए Dog की clone विधि को काम करने के लिए यह घोषणा नहीं करनी चाहिए कि यह CloneNotSupportedException फेंकता है। इसका कारण यह है कि map लिए तर्क किसी भी चेक अपवाद को फेंकने की अनुमति नहीं है।

इस कदर:

    // Note: Method is public and returns Dog, not Object
    @Override
    public Dog clone() /* Note: No throws clause here */ { ...

हालांकि यह एक बड़ी समस्या नहीं होनी चाहिए, क्योंकि यह वैसे भी सबसे अच्छा अभ्यास है। (उदाहरण के लिए प्रभाव जावा इस सलाह देता है।)

इस पर ध्यान देने के लिए गुस्तावो का धन्यवाद।

पुनश्च:

यदि आपको यह सुंदर लगता है तो आप वही कार्य करने के लिए विधि संदर्भ वाक्यविन्यास का उपयोग कर सकते हैं:

List<Dog> clonedDogs = dogs.stream().map(Dog::clone).collect(toList());



मैंने अभी एक lib विकसित किया है जो किसी इकाई ऑब्जेक्ट को क्लोन करने में सक्षम है और java.util.List ऑब्जेक्ट। बस https://drive.google.com/open?id=0B69Sui5ah93EUTloSktFUkctN0U में जार डाउनलोड https://drive.google.com/open?id=0B69Sui5ah93EUTloSktFUkctN0U और स्थैतिक विधि क्लोनलिस्टऑब्जेक्ट (सूची सूची) का उपयोग करें। यह विधि न केवल सूची को क्लोन करती है बल्कि सभी इकाई तत्वों को भी क्लोन करती है।




आपको हाथ से ArrayList को क्लोन करना होगा (इसके ऊपर पुनरावृत्ति करके और प्रत्येक तत्व को एक नए ArrayList कॉपी करना), क्योंकि clone() आपके लिए यह नहीं करेगा। इसका कारण यह है कि Clonable में निहित Clonable स्वयं Clonable को लागू नहीं कर सकती हैं।

संपादित करें : ... और वही है जो वर्खन का कोड करता है।




अन्य पोस्टर सही हैं: आपको सूची को फिर से शुरू करने और एक नई सूची में कॉपी करने की आवश्यकता है।

हालांकि ... यदि सूची में ऑब्जेक्ट्स अपरिवर्तनीय हैं - तो आपको उन्हें क्लोन करने की आवश्यकता नहीं है। यदि आपके ऑब्जेक्ट में जटिल ऑब्जेक्ट ग्राफ़ है - तो उन्हें भी अपरिवर्तनीय होने की आवश्यकता होगी।

अपरिवर्तनीयता का अन्य लाभ यह है कि वे थ्रेडसेफ भी हैं।




Links