java - method - एक सूची<Integer> से एक इंटीजर को उचित रूप से हटा रहा है




polymorphism in java (6)

यहां एक अच्छा गड़बड़ है जो मैंने अभी सामना किया है। पूर्णांक की एक सूची पर विचार करें:

List<Integer> list = new ArrayList<Integer>();
list.add(5);
list.add(6);
list.add(7);
list.add(1);

जब आप list.remove(1) निष्पादित करते हैं तो क्या होता है पर कोई शिक्षित अनुमान? list.remove(new Integer(1)) बारे में क्या? यह कुछ बुरा कीड़े पैदा कर सकता है।

remove(int index) बीच अंतर करने का उचित तरीका क्या है, जो दिए गए इंडेक्स से तत्व को हटा देता है और remove(Object o) को हटा देता है, जो पूर्णांक की सूचियों से निपटने के दौरान संदर्भ द्वारा तत्व को हटा देता है?

यहां पर विचार करने का मुख्य बिंदु एक @ निकिता का उल्लेख है - सटीक पैरामीटर मिलान ऑटो-मुक्केबाजी पर प्राथमिकता लेता है।


जब आप list.remove (1) निष्पादित करते हैं तो क्या होता है पर कोई शिक्षित अनुमान? List.remove (नया इंटीजर (1)) के बारे में क्या?

अनुमान लगाने की कोई जरूरत नहीं है। पहले मामले में List.remove(int) को कॉल किया जाएगा, और स्थिति 1 पर तत्व हटा दिया जाएगा। दूसरे मामले के परिणामस्वरूप List.remove(Integer) को बुलाया जाएगा, और जिस तत्व का मान Integer(1) बराबर है, हटा दिया जाएगा। दोनों मामलों में, जावा कंपाइलर निकटतम मिलान अधिभार का चयन करता है।

हां, यहां भ्रम (और बग) की संभावना है, लेकिन यह काफी असामान्य उपयोग-मामला है।

जब जावा 1.2 में दो List.remove विधियों को परिभाषित किया गया था, तो अधिभार अस्पष्ट नहीं थे। जावा 1.5 में जेनेरिक और ऑटोबॉक्सिंग के परिचय के साथ ही समस्या उत्पन्न हुई। पिछली दृष्टि में, अगर बेहतर विधियों में से एक को अलग नाम दिया गया तो बेहतर होता। लेकिन अब बहुत देर हो चुकी है।


आप कास्टिंग का उपयोग कर सकते हैं

list.remove((int) n);

तथा

list.remove((Integer) n);

इससे कोई फर्क नहीं पड़ता कि एन एक इंट या इंटीजर है, विधि हमेशा आपके द्वारा अपेक्षित कॉल को कॉल करेगी।

(Integer) n या Integer.valueOf(n) का उपयोग new Integer(n) से अधिक कुशल है क्योंकि पहले दो इंटीजर कैश का उपयोग कर सकते हैं, जबकि बाद में हमेशा ऑब्जेक्ट बनायेगा।


जावा हमेशा उस विधि को कॉल करता है जो आपके तर्क के लिए उपयुक्त है। ऑटो मुक्केबाजी और निहित उपक्रम केवल तभी किया जाता है जब कोई विधि न हो जिसे कास्टिंग / ऑटो मुक्केबाजी के बिना बुलाया जा सके।

सूची इंटरफ़ेस दो हटाने विधियों को निर्दिष्ट करता है (कृपया तर्कों का नामकरण नोट करें):

  • remove(Object o)
  • remove(int index)

इसका मतलब है कि list.remove(1) ऑब्जेक्ट को स्थिति 1 पर हटा देता है और remove(new Integer(1)) इस सूची से निर्दिष्ट तत्व की पहली घटना को हटा देता है।


ध्यान दें कि भले ही वीएम ने सही काम नहीं किया है, जो भी करता है, फिर भी आप इस तथ्य का उपयोग करके उचित व्यवहार सुनिश्चित कर सकते हैं कि remove(java.lang.Object) मनमानी वस्तुओं पर चल रहा है:

myList.remove(new Object() {
  @Override
  public boolean equals(Object other) {
    int k = ((Integer) other).intValue();
    return k == 1;
  }
}

मुझे 'उचित' तरीके के बारे में पता नहीं है, लेकिन जिस तरह से आपने सुझाव दिया है वह ठीक काम करता है:

list.remove(int_parameter);

दिए गए पद पर तत्व हटा देता है और

list.remove(Integer_parameter);

सूची से दिए गए ऑब्जेक्ट को हटा देता है।

ऐसा इसलिए है क्योंकि VM पहले विधि को उसी पैरामीटर प्रकार के साथ घोषित विधि खोजने का प्रयास करता है और केवल तब ऑटोबॉक्सिंग का प्रयास करता है।


ArrayList.remove(Object o) और ArrayList.remove(int index) बीच अंतर को देखने के लिए सरल जावा कोड स्पष्टीकरण

कोड:

ArrayList<Integer> list = new ArrayList<Integer>();
list.add(1);
list.add(2);
list.add(7);
list.add(4);
list.add(5);
list.add(6);
list.add(7);

for (int a = 0; a < list.size(); a++) {
    System.out.print("" + list.get(a));
}

System.out.print("  ");

//CASE 1: We are removing data object 7.
list.remove(new Integer(7));

for (int a = 0; a < list.size(); a++) {
    System.out.print("" + list.get(a));
}

System.out.print("  ");

//CASE 2: Again we are removing data object 7.
list.remove(new Integer(7));

for (int a = 0; a < list.size(); a++) {
    System.out.print("" + list.get(a));
}

System.out.print("  ");

//CASE 3: We are removing data at index 1
list.remove(1);

for (int a = 0; a < list.size(); a++) {
    System.out.print("" + list.get(a));
}

आउटपुट:

1274567
124567
12456
1456

विस्तार:

मामला 1: हम डेटा 7 के साथ पहली घटना पूर्णांक ऑब्जेक्ट को हटा रहे हैं।

मामला 2: फिर हम फिर से वही कर रहे हैं जैसे शेष डेटा से CASE 1

मामला 3: हम इंडेक्स स्थिति 1 पर डेटा निकाल रहे हैं।

निष्कर्ष:

उपरोक्त जावा कोड में उपयोग किए गए ArrayList<Integer> का एक उदाहरण लेना: ArrayList.remove(Integer object) केवल ArrayList में होने वाली विशिष्ट पूर्णांक ऑब्जेक्ट को हटा देगा। हालांकि, ArrayList.remove(int index) हमेशा दिए गए इंडेक्स स्थिति पर सरणी तत्व को हटा देगा।

के बारे में अधिक :

हम ArrayList<int> घोषित नहीं कर सकते क्योंकि यह int प्राथमिक डेटा-प्रकार है। किसी भी वर्ग जिसमें बेस-क्लास Object है केवल ArrayList जेनेरिक डेटाटाइप में निर्दिष्ट है। उदाहरण: ArrayList<String> , ArrayList<Integer> इत्यादि।





method-overloading