2009-07-26 9 views
47

क्या मुझे वास्तव में इसे स्वयं लागू करने की आवश्यकता है?एक नए आकार में एक ArrayList को हटाना

private void shrinkListTo(ArrayList<Result> list, int newSize) { 
    for (int i = list.size() - 1; i >= newSize; --i) 
    list.remove(i); 
} 
+0

FWIW neater तरीका है कि लिखने के लिए "है, जबकि लंबाई> सीमा, अंतिम पर हटा दें ई "! – Fattie

उत्तर

95

तत्वों आप निकालना और फिर लौट आए सूची पर clear फोन इच्छा की सीमा के साथ एक sublist बनाएँ।

list.subList(23, 45).clear() 

यह दृष्टिकोण List और ArrayList दोनों के लिए दस्तावेज में एक मुहावरा के रूप में उल्लेख किया है।


यहां एक पूरी तरह से यूनिट परीक्षण कोड उदाहरण है!

// limit yourHappyList to ten items 
int k = yourHappyList.size(); 
if (k > 10) 
    yourHappyList.subList(10, k).clear(); 
    // sic k, not k-1 
+0

+1 शायद सबसे तेज़ कार्यान्वयन जो बरकरार रहता है मूल – akf

+0

पर सूचक आधिकारिक दस्तावेज़ीकरण https://docs.oracle.com/javase/6/docs/api/java/util/List.html#subList(int,%20int) द्वारा पुष्टि की गई। "उदाहरण के लिए, निम्नलिखित मुहावरे सूची से तत्वों की एक श्रृंखला को हटा देता है: list.subList (से, से) .clear();" –

4

उपयोग ArrayList#removeRange() विधि:

संरक्षित शून्य removeRange (पूर्णांक fromIndex, पूर्णांक toIndex)

इस सूची से तत्वों जिसका सूचकांक fromIndex सहित उनके बीच है के सभी निकालता है, और toIndex , अनन्य। किसी भी सफल तत्व को बाईं ओर स्थानांतरित करता है (उनकी अनुक्रमणिका को कम करता है)। यह कॉल सूची में (toIndex - इंडेक्स) तत्वों को कम करता है। (यदि toIndex == fromIndex, इस आपरेशन कोई प्रभाव नहीं है।)

तो ArrayList#trimToSize() विधि का उपयोग करें:

Trims इस ArrayList उदाहरण की क्षमता सूची के मौजूदा आकार होने के लिए। एक एप्लिकेशन इस ऑपरेशन का उपयोग ArrayList इंस्टेंस के संग्रहण को कम करने के लिए कर सकता है।

+0

व्याख्या के बिना डाउनवॉइंट्स व्यर्थ हैं – dfa

+6

संरक्षित विधि ??? – ripper234

+0

यदि आप उपclass नहीं कर सकते हैं, तो sublist (मेरा दूसरा उत्तर देखें) – dfa

0

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

एक वैकल्पिक दृष्टिकोण ऐसा दिखाई दे सकता:

private void shrinkListTo(List<Result> list, int newSize) { 
    list.retainAll(list.subList(0, newSize); 
} 

दुर्भाग्य से, List.retainAll() विधि वैकल्पिक है उपवर्गों को लागू करने के लिए है, तो आप catch एक UnsupportedOperationException, करने की आवश्यकता होगी और उसके बाद कुछ और है।

private void shrinkListTo(List<Result> list, int newSize) { 
    try { 
    list.retainAll(list.subList(0, newSize); 
    } catch (UnspportedOperationException e) { 
    //perhaps log that your using your catch block's version. 
    for (int i = list.size() - 1; i >= newSize; --i) 
     list.remove(i); 
    } 
    } 
} 

यह आपके मूल के रूप में सीधे आगे नहीं है। यदि आप उस सूची के उदाहरण से बंधे नहीं हैं जिसमें आप गुजर रहे हैं, तो आप subList(int start, int end) पर कॉल करके एक नया उदाहरण आसानी से वापस कर सकते हैं, और आपको एक विधि भी करने की आवश्यकता नहीं होगी। यह एक तेज कार्यान्वयन भी होगा, जैसा कि (जावा 6 में), आपको AbstractList.SubList का उदाहरण मिल जाएगा जिसमें आपकी सूची, इसमें ऑफसेट और आकार शामिल होगा। पुनरावृत्ति की कोई आवश्यकता नहीं होगी।

आप वर्गों के बजाय इंटरफेस करने के लिए कोडिंग के लिए बहस में रुचि रखते हैं, को देखने के this favorite article by Allen Holub

+1

का उपयोग कर .retainAll() वास्तव में अक्षम होने जा रहा है। इसे ओ (एन^2) लेना होगा क्योंकि सूची के प्रत्येक तत्व के लिए, इसे जांचने के लिए उपन्यासकार के माध्यम से जाना होगा (यह नहीं जानता कि यह एक उपन्यास है) – newacct

7

वैकल्पिक रूप से आप subList विधि का उपयोग कर सकते हैं:

public static <T> List<T> shrinkTo(List<T> list, int newSize) { 
    return list.subList(0, newSize - 1); 
} 
+0

हाँ लेकिन यह मूल सूची को प्रभावित नहीं करता है। शायद हटाए जाने वाले तत्वों की अब आवश्यकता नहीं है और वह उन्हें मुक्त करना चाहता है; यह विधि इसे पूरा नहीं करेगी। – newacct

+1

जीसी इसका ख्याल रखेगा – dfa

3

मेरे समाधान:

public static void shrinkTo(List list, int newSize) { 
    int size = list.size(); 
    if (newSize >= size) return; 
    for (int i = newSize; i < size; i++) { 
     list.remove(list.size() - 1); 
    } 
} 

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

shrinkTo(yourList, 6); 
+0

मुझे काम करने लगता है। धन्यवाद! –

+0

जटिलता ओ (एन * के) होगी; के = संख्याओं को हटाने की जरूरत है। सबसे बुरे मामले में यह ओ (एन 2) तक जाएगा। –

संबंधित मुद्दे