2015-08-31 18 views
6

निम्नलिखित कोड पर विचार करें:आकार बढ़ जाता है जब गैर तुलनीय वस्तुओं जोड़ रहे हैं

import java.util.PriorityQueue; 

public class Test { 

    public static void main(String argv[]) { 
     PriorityQueue<A> queue = new PriorityQueue<>(); 
     System.out.println("Size of queue is " + queue.size()); // prints 0 
     queue.add(new A()); // does not throw an exception 
     try { 
      queue.add(new A()); // this time, an exception is thrown 
     } catch (ClassCastException ignored) { 
      System.out.println("An exception was thrown"); 
     } 
     System.out.println("Size of queue is " + queue.size()); // prints 2 
    } 

} 

class A { } // non-comparable object 

इस कोड में, एक गैर तुलनीय वस्तु पहले एक PriorityQueue में जोड़ा जाता है। यह कोड ठीक काम करता है, as already answered here

फिर, इस कतार में दूसरी वस्तु को जोड़ा जाता है। जैसा कि PriorityQueue.add जवाडोक की अपेक्षा है, ClassCastException फेंक दिया गया है क्योंकि दूसरी वस्तु पहले के तुलनीय नहीं है।

हालांकि, ऐसा लगता है कि कतार के आकार हालांकि एक अपवाद उत्पन्न हुआ था बढ़ा दिया गया था: दूसरे प्रिंट बयान आउटपुट 2 1.

के बजाय इस व्यवहार की उम्मीद है? यदि हां, तो इसके पीछे क्या कारण है और इसे कहां दस्तावेज किया गया है?

उत्तर

9

GrepCode.com के version of the source के अनुसार, ऐसा लगता है कि यह उनके कार्यान्वयन में एक बग हो सकता है।

सभी ऐड फ़ंक्शन को कॉल

public boolean add(E e) { 
    return offer(e); 
} 

प्रस्ताव समारोह इस

public boolean offer(E e) { 
    if (e == null) 
     throw new NullPointerException(); 
    modCount++; 
    int i = size; 
    if (i >= queue.length) 
     grow(i + 1); 
    size = i + 1; 
    if (i == 0) 
     queue[0] = e; 
    else 
     siftUp(i, e); 
    return true; 
} 

तरह लग रहा है आप = कि आकार पर ध्यान देंगे मैं + 1 आइटम से पहले कहा जाता है वास्तव में के माध्यम से डाला जाता है है है siftUp। जब siftUp को बुलाया जाता है, तो पहली चीज जो यह करती है वह तुलनात्मक रूप से डालने का प्रयास करती है और वास्तव में आइटम डालने से पहले अपवाद फेंकता है। इसलिए यह वास्तव में किसी आइटम को डालने के बिना आकार में वृद्धि करता है।

2

offer (add द्वारा कहा जाता है) के लिए स्रोत कोड अमान्य स्थिति है जब एक PriorityQueue कि एक Comparator नहीं है करने के लिए एक गैर Comparable वस्तु गुजर होता है कि पता चलता है।

public boolean More offer(E e) { 
    if (e == null) 
     throw new NullPointerException(); 
    modCount++; 
    int i = size; 
    if (i >= queue.length) 
     grow(i + 1); 
    size = i + 1; 
    if (i == 0) 
     queue[0] = e; 
    else 
     siftUp(i, e); 
    return true; 
} 

आकार siftUp से पहले संशोधित किया गया है कहा जाता है। siftUp विधि, आमतौर पर कतार में तत्व डालने के लिए ज़िम्मेदार है, (अंत में) ClassCastException फेंकता है, लेकिन आकार को पहले ही संशोधित कर दिया गया है, जिससे आकार गलत हो गया है।

यह प्रलेखित के लिए नहीं दिखाई देता हो size वृद्धि हो जाएगा कि भले ही एक ClassCastException होता है। If/else के बाद और वापसी कथन से पहले size = i + 1; लाइन को रखना एक साधारण फिक्स होगा।

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