2010-03-23 9 views
14

यह ज्ञात है कि जावा ऐरेलिस्ट को सरणी का उपयोग करके कार्यान्वित किया जाता है और 10 की क्षमता के साथ शुरू होता है और इसका आकार 50% बढ़ा देता है। वर्तमान ArrayList क्षमता कैसे प्राप्त करें ArrayList का आकार नहीं।जावा में ArrayList की क्षमता कैसे प्राप्त करें?

Thx

+3

आप इस जानकारी की आवश्यकता क्यों करते हैं? –

+1

छाल .. कुछ भी विशिष्ट नहीं .. मेरे पास एक साक्षात्कार में – JavaUser

+0

Google ने मुझे यहां ले जाया था। कारण मुझे इस जानकारी की आवश्यकता है - मेरे पास एक ArrayBlockingQueue है जिसे मैं किसी अन्य संग्रह में परिणाम, प्रसंस्करण और परिणामों को संग्रहीत कर रहा हूं। सोचा कि परिणाम संग्रह के लिए प्रारंभिक क्षमता का उपयोग करना अच्छा होगा जो एबीक्यू की क्षमता से मेल खाता है। इतना अजीब उपयोग मामला नहीं, नहीं? मेरे आस-पास के अन्य तरीके भी हैं (उदाहरण के लिए एक स्थिर फाइनल के रूप में क्षमता भंडारण करना और संदर्भ देना), लेकिन सभी मामलों में जरूरी नहीं है। – ericsoco

उत्तर

16

मुझे नहीं लगता कि यह संभव है है। आपका उपयोग केस क्या है? मेरा मानना ​​है कि सी # ArrayLists में एक .capacity संपत्ति है, लेकिन जावा ArrayList कक्षा इस जानकारी का पर्दाफाश नहीं करता है।

आपके पास ऐसा निर्माता है जो प्रारंभिक क्षमता तर्क लेता है, और आपके पास सुनिश्चित क्षमता क्षमता() विधि है जिसका उपयोग आप वृद्धिशील पुनर्वितरण की मात्रा को कम करने के लिए कर सकते हैं।

आपके पास ट्रिम टॉइस() विधि भी है जिसका उपयोग आप स्मृति उपयोग के बारे में चिंतित होने पर कर सकते हैं।

+1

वेक्टरों के संबंध में वही मामला क्या है? – JavaUser

+3

वेक्टर की क्षमता() विधि है जो वर्तमान क्षमता को वापस लाती है। क्या आपने एपीआई को देखने के लिए समय निकाला है? http://java.sun.com/j2se/1.4.2/docs/api/java/util/Vector.html –

+2

नहीं mbaird, मैं सिर्फ अपने answer.Thx – JavaUser

0

याद रखें अगर यह है लेकिन आप इसे ऐरेलिस्ट के स्रोत कोड को देखकर स्वयं कर सकते हैं। जावा डेवलपर्स को एसडीके के साथ बंडल किए गए स्रोत कोड का लाभ उठाना चाहिए।

+0

हालांकि यह सुनिश्चित नहीं है कि रनटाइम पर वर्तमान क्षमता को खोजने में उसकी सहायता करने के लिए यह कितना उपयोगी होगा। जब तक उन्होंने स्रोत नहीं लिया और क्षमता का पर्दाफाश करने के लिए एक विधि जोड़ा, और फिर हर जगह ArrayList के अपने कस्टम संस्करण का उपयोग किया। –

+0

हाहा, पहले s.o upvote तो s.o else downvote :)) मैंने उसे एक छड़ी दी लेकिन आपने उसे एक मछली दी ... अब क्या, वे वेक्टर, लिंक्डलिस्ट के लिए पूछेंगे ..? :)) – instcode

+0

@mbaird 'आप इसे स्वयं कर सकते हैं' शायद इसका मतलब है कि आप स्रोत कोड को देखकर क्षमता प्राप्त करने का कोई तरीका ढूंढ सकते हैं, 'नहीं, आप स्रोत कोड बदल सकते हैं'। – bjornars

0

मैं सिर्फ ArrayList वर्ग पर सूरज प्रलेखन की जाँच की है, और केवल विधि मैंने देखा कि क्षमता से संबंधित ensureCapacity था (int minCapacity) है, जो वास्तव में आप क्या चाहते हैं नहीं है। सौभाग्य!

2

ArrayList's spec पर देख रहे हैं मुझे कोई जानकारी नहीं है जो यह जानकारी प्रदान करता है।

जिसके अनुसार, ensureCapacity विधि सही दिशा में एक कदम की तरह प्रतीत होता है (सावधानी: यह है एक सही जवाब की गारंटी नहीं है): जब कहा जाता है कि यह सुनिश्चित करता है कि क्षमता कम से कम निर्दिष्ट तर्क है। इसलिए, यदि ArrayList कार्यान्वयन क्षमता सुनिश्चित करने के लिए इस विधि का उपयोग करता है (जैसा कि कुछ निजी विधि को कॉल करने के विपरीत है/प्रासंगिक क्षेत्रों को सीधे जोड़ना) आप इस विधि को ओवरराइड करके वर्तमान क्षमता प्राप्त कर सकते हैं। आपको उसी तरह trimToSize() ओवरराइड करने की भी आवश्यकता है।

बेशक, यह समाधान ArrayList (किसी अन्य विक्रेता से JVM पर) के विभिन्न कार्यान्वयन के रूप में बहुत पोर्टेबल नहीं है, चीजें अलग-अलग कर सकती हैं।

यहाँ कोड की तरह

public class CapacityTrackingArrayList<T> extends ArrayList<T> { 

    // declare a constructor for each ArrayList constructor ... 


    // Now, capacity tracking stuff: 
    private int currentCapacity = 10; 

    public int getCapacity() { return currentCapacity; } 

    public void ensureCapacity(int arg) { 
    currentCapacity = arg; 
    super.ensureCapacity(arg); 
    } 

    public void trimToSize() { currentCapacity = size(); super.trimToSize(); } 

} 
+1

सुनिश्चित करें क्षमता() केवल यह सुनिश्चित करता है कि इसमें कम से कम इतना स्थान हो। यदि इसमें अधिक जगह है तो यह कुछ भी नहीं करेगा। यदि बाद में आप तत्व जोड़ते रहते हैं ताकि इसे और भी अधिक की आवश्यकता हो, तो यह बढ़ेगा। इन मामलों में से कोई भी आपके उदाहरण कोड द्वारा संभाला नहीं जाएगा। आपका पूरा कोड आपको यह याद दिलाएगा कि आपने कैपेसिटी() को पहले सुनिश्चित करने के लिए किस मूल्य को पारित किया था, जिसके बाद वास्तविक क्षमता पर कोई वास्तविक असर नहीं हो सकता है। –

+0

हर तरह से, मैं नहीं कहता कि यह एक आदर्श समाधान है और न ही यह एक पोर्टेबल है। यह सही दिशा में सिर्फ एक कदम है। –

6

देखना चाहिए कि कैसे आप प्रतिबिंब द्वारा यह प्राप्त कर सकते हैं:

public abstract class ArrayListHelper { 

    static final Field field; 
    static { 
     try { 
      field = ArrayList.class.getDeclaredField("elementData"); 
      field.setAccessible(true); 
     } catch (Exception e) { 
      throw new ExceptionInInitializerError(e); 
     } 
    } 

    @SuppressWarnings("unchecked") 
    public static <E> int getArrayListCapacity(ArrayList<E> arrayList) { 
     try { 
      final E[] elementData = (E[]) field.get(arrayList); 
      return elementData.length; 
     } catch (Exception e) { 
      throw new RuntimeException(e); 
     } 

    } 
} 
+4

यह बेहद असफल हो जाएगा, जब फ़ील्ड को 'elementData' नहीं कहा जाता है। और चूंकि उस नाम को एपीआई में निर्दिष्ट नहीं किया गया है, इसलिए कोई कार्यान्वयन (और कोई संस्करण!) इसे पूरी तरह से कुछ और कहने के लिए स्वतंत्र है। –

+0

@ जोचिमसॉयर अभी भी elementData कहलाता है, यह नहीं देखते कि वे इसे क्यों बदल देंगे, फिर भी यदि आप करते हैं तो आप कोड को आसानी से संशोधित कर सकते हैं! – BaSsGaz

0

आप ArrayList के बजाय वेक्टर उपयोग कर सकते हैं। वेक्टर क्षमता() विधि का समर्थन करता है। 10.once अधिकतम आकार तक पहुँच जाता है ArrayList की

+3

ओपी स्पष्ट रूप से 'वेक्टर 'नहीं,' ऐरेलिस्ट 'की क्षमता चाहता था। – Manuel

+0

वेक्टर ArrayList के समान प्राप्त कर सकते हैं। यह जावा की गलती है कि क्षमता का पर्दाफाश न करें। यदि आप क्षमता को नहीं जानते हैं तो आप ट्रिमटोसाइज को कब कॉल कर सकते हैं? हर समय trimtosize कॉल करने के लिए यह कुशल नहीं है। ऐसी स्थिति में वेक्टर का उपयोग करने के लिए परिवर्तन एक अच्छा विचार है। – jack

0

डिफ़ॉल्ट क्षमता है, नई क्षमता हो जाएगा:

नई क्षमता = (currentcapacity * 3/2) +1।

0

ऐरेलिस्ट का उपयोग करने का पूरा बिंदु गतिशील रूप से नया तत्व जोड़ना है, इसलिए ArrayList की क्षमता प्राप्त करने के लिए कोई विशिष्ट विधि नहीं है।

हर बार जब हम एक तत्व जोड़ते हैं तो गतिशील रूप से पुनर्वितरण का कारण बनता है और चूंकि पुनर्वितरण समय के हिसाब से महंगा होता है, फिर से पुनर्वितरण को रोकने से प्रदर्शन में सुधार होता है और इसलिए आप सुनिश्चित करें कि क्षमता सुनिश्चित करने के लिए मैन्युअल रूप से ऐरेलिस्ट की क्षमता बढ़ाएं (लेकिन फिर से आप यह नहीं ढूंढ सकते ArrayList की क्षमता।

0

इस कोड प्रतिबिंब का उपयोग करता है एक ArrayList की क्षमता प्राप्त करने के लिए:

package examples1; 

import java.util.ArrayList; 
import java.util.List; 
import java.lang.reflect.Field; 

public class Numbers { 

    public static void main(String[] args) throws Exception { 
     List<Integer> numbers = new ArrayList<>(); 
     numbers.add(1); 
     System.out.println(getCapacity(numbers)); 
    } 

    static int getCapacity(List al) throws Exception { 
     Field field = ArrayList.class.getDeclaredField("elementData"); 
     field.setAccessible(true); 
     return ((Object[]) field.get(al)).length; 
    } 
} 

हो जाएगा ताकि उत्पादन: 10

नोट्स:

  1. getCapacity() विधि http://javaonlineguide.net/2015/08/find-capacity-of-an-arraylist-in-java-size-vs-capacity-in-java-list-example.html पर मूल से संशोधित
  2. ध्यान दें कि सूची में पहले जोड़े जाने के बाद 10 की डिफ़ॉल्ट क्षमता दी जाती है। आप जोड़ने से पहले यह कोशिश करते हैं, तो आप को जोड़े बिना 0
  3. क्षमता बाध्य करने के लिए का उत्पादन मिल जाएगा, तो जैसे निर्माता में इसे पारित:

    List<Integer> numbers = new ArrayList<>(20); 
    
संबंधित मुद्दे