2012-01-19 20 views
7

बाहर आइटम जोड़ने सोच वहाँ अपने वर्तमान आकार से बड़ी की स्थिति में जावा के ArrayList में कोई आइटम जोड़ने के लिए एक कारगर तरीका है कि क्या:जावा ArrayList वर्तमान आकार

परिदृश्य:

ArrayList<Item> items = new ArrayList<Item>; 
    ... let's say I add three elements 

अब मैं चाहते हैं स्थिति 10 (10 करने के लिए 3 से आइटम छोड़ने शून्य पर)

items.add(10,newItem); // item.size() == 3 

वहाँ एक कारगर तरीका आकार बदलने है/nulls के साथ एक ArrayList भरने में एक आइटम जोड़ने के लिए? ।।

जावा के कार्यान्वयन बनाता आकार क्षेत्र निजी :-(..

+0

आपको शायद हैश मैप या सॉर्टेड मैप का उपयोग करना चाहिए। –

+0

ठीक है, मानचित्र का उपयोग मेमोरी राइसन का समाधान नहीं है, हम अंत में जानते हैं कि संरचना पूर्ण है -> TIntObjectHashMap (trove) शायद – ic3

+0

ए हैश मैप आदेश का समर्थन नहीं करता है। एक सॉर्टेड मैप एक बेहतर विकल्प है। –

उत्तर

6

सबसे अच्छी बात आप कर सकते हैं imho items.addAll(Collections.nCopies(6, null)) है और उम्मीद है कि ArrayList आंतरिक रूप से इसे मजबूत करने के लिए कुछ व्यवहार लागू करता है

+0

यह अच्छा है लेकिन देखने के प्रदर्शन बिंदु से थोड़ी डरावनी है – ic3

+0

अच्छी तरह से एनकोपी केवल एक सूची बनाती है-एक ऐरे के लिए रैपर और इस तरह आपका ऐरेलिस्ट सिस्टम का उपयोग करने में सक्षम है पर अशक्त के आधार पर भरने के लिए कैसे स्मार्ट यह – Hachi

+1

सार्वजनिक बूलियन addAll (संग्रह ग) { \t वस्तु [] एक = c.toArray() कार्यान्वित किया जाता है .arraycopy; int numNew = a.length; \t सुनिश्चित करें क्षमता (आकार + numNew); // वृद्धि modCount सिस्टम।एरेकॉपी (ए, 0, एलिमेंटडाटा, आकार, numNew); आकार + = numNew; \t वापसी संख्या नया! = 0; } – ic3

-2

उपयोग निर्माता ArrayList(int initialCapacity) इस तरह आप आरंभिक क्षमता निर्धारित कर सकते हैं

+1

प्रारंभिक क्षमता आकार नहीं है -> थ्रेड में मुख्य "java.lang.IndexOutOfBoundsException: इंडेक्स: 9, आकार: 0 – ic3

+0

आज़माएं : सार्वजनिक स्थैतिक शून्य मुख्य (स्ट्रिंग [] तर्क) { ऐरेलिस्ट सूची = नया ऐरेलिस्ट (10); list.add (9,3); } – ic3

0

मैं यहां एक सूची के बजाय SortedMap का उपयोग करने पर विचार करूंगा। यह इंडेक्स के अस्तित्व में रहने की अनुमति नहीं देगा:

SorteMap<Integer, Item> myMap = new TreeMap<Integer, Map>(); 
int i=0; 
myMap.put(i++, first); 
myMap.put(i++, second); 
myMap.put(i++, third); 
myMap.put(10, other); 

यदि कोई नक्शा वास्तव में काम नहीं करेगा, जैसा आपने कहा था। मैं फिर ArrayList के चारों ओर एक सजावट बनाने का सुझाव देंगे। सम्मिलित विधि में, खाली स्थानों को भरने के लिए नल जोड़ें। कक्षा के निर्माण को कम करने के लिए मैं गुवा के ForwardingList का उपयोग करने का सुझाव दूंगा। इस तरह आपको केवल एक विधि को लागू करना होगा।

+0

जो स्मृति raisons के लिए एक विकल्प नहीं है ... – ic3

+0

यहाँ स्मृति के साथ क्या गलत है? @ जॉन बी - इस कोड को सही करें। –

+0

1mio ऑब्जेक्ट के साथ TreeMap बड़ा है। – ic3

0

नहीं, तो आप इस, ऐसा नहीं कर सकते लेकिन अगर आप ऐसा करना चाहते हैं, तो इस तरह के रूप सूचकांक शेष में खाली ऑब्जेक्ट जोड़ने ..

ArrayList<Object> items = new ArrayList<Object>(); 
    items.add(new Object()); 
    items.add(new Object()); 
    items.add(new Object()); 
    items.add(3,new Object()); 
+0

असल में मैं कुछ और अधिक सुरुचिपूर्ण चीज़ों के लिए लटक रहा था :-) – ic3

2

इसके बारे में कैसे?

ArrayList<Item> items = new ArrayList<Item>(); 

items.add(new Item(0)); 
items.add(new Item(1)); 
items.add(new Item(2)); 

items.addAll(Collections.<Item>nCopies(7, null)); 
items.add(10,new Item(10)); 

System.out.println(items); 

प्रिंट

[0, 1, 2, null, null, null, null, null, null, null, 10] 
+0

अधिक मजबूत विकल्प के रूप में '7' के बजाय' 10 - items.size' का उपयोग करें। –

0

तो स्मृति और सूचकांक बहुत महत्वपूर्ण है कि एक सामान्य सरणी का उपयोग करें।

जब यह छोटा उपयोग System.arraycopy होता है, जिस तरह से ऐरेलिस्ट इसे आंतरिक करता है।

-

भले ही आप ArrayList उपयोग करें और यह ArrayList (पूर्णांक initialCapacity) कॉपी-संचालन का एक बहुत से बचने के लिए -Constructor

1

उपयोग ट्री-मैप के बजाय का प्रयोग उचित है एक लाख वस्तुओं की है। मेमोनी कंसुशन की जांच करने के लिए यहां सरल उदाहरण दिया गया है। पहले और दूसरे परीक्षण को अलग से चलाएं और ढेर आकार की जांच के लिए jvisualvm का उपयोग करें। कई बार जीसी प्रदर्शन करना याद रखें।

public class Test { 


      public static void main(String[] args) throws InterruptedException { 
       String s = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque metus."; 


       //Test 1 
       ArrayList<String> l = new ArrayList<String>(); 

       for (int i = 0; i < 1000000; i++) { 
        l.add(s + " " + i); 
        l.addAll(Collections.nCopies(i % 10, (String)null)); //Add some nulls 
       } 
       //Heap is > 5MB 

       //Test 2 uncomment and comment test 1 
    //   SortedMap<Integer, String> map = new TreeMap<Integer, String>(); 
    //   for (int i = 0; i < 1000000; i++) { 
    //    map.put(i,s + " " + i); 
    //   } 
       //Heap is < 5MB 

       Thread.sleep(100000); 

      } 
    } 

ऐसा लगता है कि TreeMap संस्करण की तरह और भी कम स्मृति ArrayList संस्करण की तुलना में लगता है। अपने आप को जांचो।

+0

पीटर, ऐरेलिस्ट एक सरणी है और थोड़ा और है। एक पूर्ण सरणी किसी भी अन्य संरचना की तुलना में अधिक आकार लेती है? ... मुझे लगता है कि आपके उदाहरण में कोई समस्या है (मुझे यकीन है) – ic3

+0

हम एक पूर्ण सरणी के बारे में बात कर रहे हैं .. – ic3

+0

सरणी है (एस - स्ट्रिंग, एन-नल): snsnnsnnnsnnnnsnnnnns nnnnnnsnnnnnnns ... आदि बहुत कुछ है संदर्भों के लिए आरक्षित स्मृति की लेकिन शून्य पर सेट। TreeMap में यह समस्या नहीं है। जैसा कि आपने कहा था कि यह एक सरणी है। यहां तक ​​कि 1mio nulls की सरणी अभी भी स्मृति की लागत है। यह आपकी सूची है कि "घना" कैसे है। –

0

@ आईसीक्यूब- आपने कहा, यह सूची लगभग 9 0% पूर्ण होनी चाहिए। इस समाधान के लिए मेरा विचार है:

  • कि वास्तव में आप लक्ष्य आकार पता है - का उपयोग सादे सरणी
  • आप लक्ष्य आकार के बारे में पता कर रहे हैं - अधिक से अधिक निकट आकार को लक्षित करने के आरंभिक क्षमता के साथ उपयोग ArrayList। लोगों ने कहा कि l.addAll(Collections.nCopies(n, (String)null)); के साथ नल रखो।
  • यदि आप लक्ष्य आकार नहीं जानते हैं - तो आपके ऐरेलिस्ट का आकार कई बार बदला जाएगा। आकार बदलने का अर्थ है संपूर्ण अंतर्निहित सरणी की प्रतिलिपि बनाना (यह Arrays.copyOf का उपयोग करता है)। आप कल्पना कर सकते हैं कि अगर सरणी की प्रतिलिपि बनाई जाती है तो क्या होता है - जीसी के पास बहुत सारे काम हैं। तब TreeMap का प्रयोग करें।
संबंधित मुद्दे