एक java.util की नकल कैसे करें। दूसरे java.util में देखें


135

मेरे पास एक List<SomeBean>वेब सेवा से आबादी है। मैं उस सूची की सामग्री को उसी प्रकार की खाली सूची में कॉपी / क्लोन करना चाहता हूं। एक सूची की प्रतिलिपि बनाने के लिए एक Google खोज ने मुझे Collections.copy()विधि का उपयोग करने का सुझाव दिया । मेरे द्वारा देखे गए सभी उदाहरणों में, गंतव्य सूची में प्रतिलिपि बनाने के लिए सही संख्या में आइटम होने चाहिए थे।

जैसा कि मैं जिस सूची का उपयोग कर रहा हूं वह वेब सेवा के माध्यम से आबाद है और इसमें सैकड़ों वस्तुएं हैं, मैं उपरोक्त तकनीक का उपयोग नहीं कर सकता। या मैं इसका गलत उपयोग कर रहा हूँ ?? !! वैसे भी, यह काम करने के लिए, मैंने ऐसा कुछ करने की कोशिश की, लेकिन मुझे अभी भी एक मिल गया है IndexOutOfBoundsException

List<SomeBean> wsList = app.allInOne(template);

List<SomeBean> wsListCopy=new ArrayList<SomeBean>(wsList.size());   
Collections.copy(wsListCopy,wsList);
System.out.println(wsListCopy.size());

मैंने उपयोग करने की कोशिश की wsListCopy=wsList.subList(0, wsList.size())लेकिन मुझे ConcurrentAccessExceptionकोड में बाद में मिला । मारो और मुकदमा करो। :)

वैसे भी, मेरा सवाल सरल है, मैं अपनी सूची की पूरी सामग्री को दूसरी सूची में कैसे कॉपी कर सकता हूं? पाठ्यक्रम के माध्यम से नहीं।


11
कोई भी कॉपी पाठ्यक्रम का उपयोग करेगा। आप इसे दूर छिपा सकते हैं लेकिन यह अभी भी रहेगा।
पीटर लाव्रे

1
सबसे पहले: क्या आप सुनिश्चित हैं कि आपको उस सूची की प्रतिलिपि बनाने की आवश्यकता है? ऐसा करने में आपकी प्रेरणा क्या है?
पितृका

2
हाँ, पुनरावृति बस उस परतों के नीचे छिपी हुई है। लेकिन किसी भी पुनरावृत्ति उत्तर को रोकने के लिए टिप्पणी को जोड़ा गया था। :)
मोनो जैमून

@ppeterka मैं हटाए () जैसे सूची पर परिचालन कर रहा हूं। यह सूची को उसके मूल डेटा को नुकसान पहुंचाने का कारण बनता है। और "डेटा" भी बाद में आवश्यक है।
मोनो जैमून

सूची का वास्तविक प्रकार क्या है, जो वापस आ रहा है app.allInOne(template)? ArrayList?
एंडरमोनी

जवाबों:


235

बस इस का उपयोग करें:

List<SomeBean> newList = new ArrayList<SomeBean>(otherList);

नोट: अभी भी थ्रेड सुरक्षित नहीं है, यदि आप otherListकिसी अन्य थ्रेड से संशोधित करते हैं , तो आप उदाहरण के लिए, otherList(और यहां तक ​​कि newList) a बनाना चाहते हैं CopyOnWriteArrayList- या लॉक आदिम का उपयोग कर सकते हैं, जैसे कि ReentrantReadWriteLock जो भी सूचियां हैं, पढ़ने / लिखने के लिए एक्सेस करना। समवर्ती रूप से पहुँचा।


1
अब, मैं वास्तव में बेवकूफ महसूस कर रहा हूँ :) मुझे उम्मीद है कि इस तरह से इसका निर्माण किसी भी तरह नहीं होगा ConcurrentAccessException
मोनो जैमून


5
+1 यदि उसे समवर्ती (एक्सक्लूज़न) मिल रहा है, तो उसके पास एक समसामयिक समस्या है जिसे उसे पहले ठीक करने की आवश्यकता है।
पीटर लाव्रे

5
यदि प्रश्न "कॉपी / क्लोन" का उल्लेख किया जाता है तो यह उत्तर इतने सारे अंक क्यों प्राप्त कर रहा है? यह, जब तक कि कुछ अन्य उत्तरों का क्लोनिंग से कोई लेना-देना नहीं है। संग्रह के अंदर वस्तुओं के लिए समान संदर्भ रखे जाएंगे जो भी संग्रह / स्ट्रीम विशिष्ट उपयोगिता-विधियों का उपयोग करते हैं।
युरानोस

3
उत्तर गलत है। सामग्री की प्रतिलिपि नहीं बनाई गई है। केवल यह संदर्भ है।
अविश्वसनीय जन

33

यह करने के लिए एक बहुत अच्छा जावा 8 तरीका है:

List<String> list2 = list1.stream().collect(Collectors.toList());

निश्चित रूप से यहाँ लाभ यह है कि आप सूची के भाग की केवल कॉपी और फ़िल्टर कर सकते हैं।

जैसे

//don't copy the first element 
List<String> list2 = list1.stream().skip(1).collect(Collectors.toList());

4
परिणामी सूची मूल सूची की एक गहरी-प्रति या उथली प्रति है?
विज्ञापन इनफिनिटम

7
उथली प्रति।
kap

3
यह, दुख की बात है, यह भी धागा सुरक्षित नहीं है। यह मानते listहुए कि कलेक्टर चल रहा है, एक बदल ConcurrentModificationExceptionदिया जाता है।
सी-ओटो

@, अंतिम तत्व की नकल कैसे छोड़ें?
सीकेएम

@ चंद्रेश अंतिम तत्व की नकल करना छोड़ दें, आप बस इस्तेमाल करेंगे.limit(list1.size() - 1)
मैथ्यू कारपेंटर

13
originalArrayList.addAll(copyArrayofList);

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

यदि आप साइड इफेक्ट नहीं चाहते हैं, तो आपको ओरिजनल एट्रेलिस्ट से कॉपीअरेफ्रॉफिस्ट तक के प्रत्येक तत्व को कॉपी करने की जरूरत है, जैसे कि फॉर फॉर या लूप का उपयोग करना।


2
यह यहाँ कुछ सच्चे उत्तरों में से एक है, क्योंकि यह निर्दिष्ट करता है कि #addAll एक उथली प्रतिलिपि बनाता है, साथ ही साथ गहरी प्रतिलिपि कैसे बनाता है। अधिक जानकारी: stackoverflow.com/questions/715650/…
cellepo

7

मैंने ऐसा कुछ करने की कोशिश की, लेकिन मुझे अभी भी एक IndexOutOfBoundsException मिली।

मुझे एक समवर्तीअनुप्रयोग मिला

इसका मतलब है कि आप सूची को संशोधित कर रहे हैं, जबकि आप इसे कॉपी करने की कोशिश कर रहे हैं, सबसे अधिक संभावना एक और धागे में। इसे ठीक करने के लिए आपको या तो

  • एक संग्रह का उपयोग करें जो समवर्ती पहुंच के लिए डिज़ाइन किया गया है।

  • संग्रह को उचित रूप से लॉक करें ताकि आप उस पर पुनरावृति कर सकें (या आपको एक विधि को कॉल करने की अनुमति दें जो आपके लिए ऐसा करता है)

  • मूल सूची की प्रतिलिपि बनाने से बचने के लिए दूर खोजें।


4

जावा 10 से शुरू :

List<E> oldList = List.of();
List<E> newList = List.copyOf(oldList);

List.copyOf()Listदिए गए तत्वों से युक्त एक अपरिवर्तनीय रिटर्न देता है Collection

दिए गए Collectionनहीं होना चाहिए null, और इसमें कोई nullतत्व नहीं होना चाहिए ।

इसके अलावा, यदि आप एक गहरी प्रतिलिपि बनाना चाहते हैं, तो आप यहांList कई अच्छे उत्तर पा सकते हैं ।


3

जावा 8 के साथ एक और तरीका है एक शून्य-सुरक्षित तरीके से।

List<SomeBean> wsListCopy = Optional.ofNullable(wsList)
    .map(Collection::stream)
    .orElseGet(Stream::empty)
    .collect(Collectors.toList());

यदि आप एक तत्व को छोड़ना चाहते हैं।

List<SomeBean> wsListCopy = Optional.ofNullable(wsList)
    .map(Collection::stream)
    .orElseGet(Stream::empty)
    .skip(1)
    .collect(Collectors.toList());

जावा 9+ के साथ, वैकल्पिक की धारा पद्धति का उपयोग किया जा सकता है

Optional.ofNullable(wsList)
    .stream()
    .flatMap(Collection::stream)
    .collect(Collectors.toList())

1

मैं एक ही समस्या हो रही थी ConcurrentAccessException और mysolution लिए किया गया था:

List<SomeBean> tempList = new ArrayList<>();

for (CartItem item : prodList) {
  tempList.add(item);
}
prodList.clear();
prodList = new ArrayList<>(tempList);

तो यह समय पर केवल एक ही ऑपरेशन का काम करता है और छूटने से बचता है ...


1

मैंने कुछ इसी तरह की कोशिश की और समस्या को पुन: उत्पन्न करने में सक्षम था (IndexOutOfBoundsException)। नीचे मेरे निष्कर्ष हैं:

1) कलेक्शंस.कॉपी (डेस्टलिस्ट, सोर्सलिस्ट) का कार्यान्वयन पहले आकार () विधि को कॉल करके गंतव्य सूची के आकार की जांच करता है। चूंकि आकार () विधि में कॉल हमेशा सूची में तत्वों की संख्या (इस मामले में 0) लौटाएगा, कंस्ट्रक्टर ArrayList (क्षमता) बैकिंग सरणी की केवल प्रारंभिक क्षमता सुनिश्चित करता है और इसका कोई संबंध नहीं है सूची का आकार। इसलिए हम हमेशा IndexOutOfBoundsException प्राप्त करते हैं।

2) निर्माणकर्ता का उपयोग करने के लिए एक अपेक्षाकृत सरल तरीका है जो एक संग्रह को अपने तर्क के रूप में लेता है:

List<SomeBean> wsListCopy=new ArrayList<SomeBean>(wsList);  

0

पुन:, indexOutOfBoundsExceptionआपकी सबलिस्ट अर्ल्स समस्या है; आपको आकार -1 में सबलिस्ट को समाप्त करने की आवश्यकता है। शून्य-आधारित होने के कारण, किसी सूची का अंतिम तत्व हमेशा आकार -1 होता है, आकार की स्थिति में कोई तत्व नहीं होता है, इसलिए त्रुटि होती है।



0

मैं कोई सही उत्तर नहीं देख सकता। यदि आप एक गहरी प्रतिलिपि चाहते हैं तो आपको मैन्युअल रूप से पुनरावृति और ऑब्जेक्ट को कॉपी करना होगा (आप एक कॉपी कंस्ट्रक्टर का उपयोग कर सकते हैं)।


यह यहाँ कुछ सच्चे उत्तरों में से एक है। अधिक जानकारी: stackoverflow.com/questions/715650/…
cellepo

-2

यदि आप एक सूची में बदलाव नहीं करना चाहते हैं तो दूसरी सूची को प्रभावित करने की कोशिश करें। यह मेरे लिए काम
करता है आशा है कि यह मदद करता है।

  public class MainClass {
  public static void main(String[] a) {

    List list = new ArrayList();
    list.add("A");

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

    System.out.println(list);
    System.out.println(list2);

    list.clear();

    System.out.println(list);
    System.out.println(list2);
  }
}

> Output:   
[A]  
[A]  
[]  
[A]

-3

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

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.