2009-04-10 16 views
21

दिए गए सरणी सूची में ऑब्जेक्ट ढूँढना मेरे पास वास्तव में कुछ प्रश्न हैं।जावा विधि: ज्ञात विशेषता मान

private int id; 
private int id_mother; 
private int id_father; 
private String name=""; 
private String owner=""; 
private String bDate=""; 

मैं भी एक वर्ग आर्काइव जो कुत्ता का दृष्टांत और एक ArrayList में कुत्ता वस्तुओं डाल सकते हैं:

मैं एक वर्ग निम्नलिखित उदाहरण क्षेत्रों के साथ कुत्ता है।

मैं पुरालेख में एक विधि लिखने की कोशिश कर रहा हूं जो आईडी के रूप में पूर्णांक लेता है और ऐरेलिस्ट के माध्यम से देखता है, और उस आईडी वाले ऑब्जेक्ट को वापस देता है।

private Dog getDog(int id){ 
    Dog dog = new Dog(); 
    int length=getSize(); 
    int i=0; 

    dog=al.get(i); 
    i++; 

    while(dog.getId()!=id && i<length) 
     dog=al.get(i); 
     i++; 

    if(dog.getId()!=id) 
     dog=null; 
    return dog; 
}//end getDog 

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

+0

रहे getSize() और अल परिभाषित कैसे हल? – cobbal

उत्तर

16

whilewhile के बाद अभिव्यक्ति या ब्लॉक पर लागू होता है।

आप न एक ब्लॉक है, तो उसके बाद केवल एक बार होता आपके जबकि dog=al.get(i);

while(dog.getId()!=id && i<length) 
       dog=al.get(i); 

सब कुछ अभिव्यक्ति के साथ समाप्त होता है।

कुत्ते को नया करने का कोई कारण नहीं है, क्योंकि आप कभी भी कुत्ते का उपयोग नहीं कर रहे हैं; आप तुरंत अपने कुत्ते संदर्भ में सरणी से एक कुत्ता असाइन करते हैं।

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

संपादित करें: यह डोनडोडेड क्यों किया गया था ?? ओपी से

टिप्पणी: एक कुत्ता का एक नया उदाहरण बनाने के लिए नहीं होने के संबंध में

आगे सवाल। अगर मैं सरणी सूची से ऑब्जेक्ट्स की प्रतियां ले रहा हूं, तो मैं इसे किसी ऑब्जेक्ट के बिना सरणी सूची से कैसे निकाल सकता हूं जिसमें मैंने इसे रखा था? मैंने अभी भी ध्यान दिया कि मैंने थोड़ी देर के दौरान ब्रैकेट नहीं किया था।

एक जावा संदर्भ और जिस वस्तु को संदर्भित करता है वह अलग-अलग चीजें हैं। वे एक सी ++ संदर्भ और वस्तु की तरह बहुत अधिक हैं, हालांकि जावा संदर्भ को सी ++ पॉइंटर की तरह फिर से इंगित किया जा सकता है।

उपरोक्त है कि Dog dog; या Dog dog = null आपको एक संदर्भ देता है जो किसी भी वस्तु को इंगित करता है। new Dog() एक ऑब्जेक्ट बनाता है जिसे इंगित किया जा सकता है।

dog = al.get(i) के साथ इसका मतलब है कि संदर्भ अब कुत्ते संदर्भ को इंगित करता है al.get(i) द्वारा लौटाया गया। समझें, जावा में, वस्तुओं को कभी वापस नहीं किया जाता है, केवल वस्तुओं के संदर्भ (जो स्मृति में ऑब्जेक्ट के पते हैं)।

आपके द्वारा चुने गए कुत्ते का सूचक/संदर्भ/पता अब खो गया है, क्योंकि कोई कोड इसका संदर्भ नहीं देता है, क्योंकि रेफरेंस को al.get() से प्राप्त संदर्भ के साथ प्रतिस्थापित किया गया था। आखिर में जावा कचरा कलेक्टर उस वस्तु को नष्ट कर देगा; सी ++ में आप स्मृति को "लीक" करेंगे।

उपरोक्त यह है कि आपको एक चर बनाने की आवश्यकता है जो कुत्ते को संदर्भित कर सके; आपको new के साथ कुत्ता बनाने की आवश्यकता नहीं है।

(सच में आपको संदर्भ बनाने की आवश्यकता नहीं है, जैसा कि आपको वास्तव में क्या करना चाहिए, यह लौट रहा है कि मैप अपने() फ़ंक्शन से क्या लौटाता है। यदि नक्शा कुत्ते पर पैरामीट्रिज्ड नहीं है, तो इस तरह : Map<Dog>, तो आपको रिटर्न प्राप्त करने की आवश्यकता होगी, लेकिन आपको संदर्भ की आवश्यकता नहीं होगी: return (Dog) map.get(id); या यदि नक्शा पैरामीटर किया गया है, return map.get(id)। और वह एक पंक्ति आपका पूरा कार्य है, और यह तेज़ होगा अधिकांश मामलों के लिए एक सरणी को पुन: सक्रिय करना।)

+0

मुझे नहीं लगता कि यह वह जवाब है जिसे वह ढूंढ रहा है। आप उस लूप के बारे में सही हैं जो इसे नहीं करना चाहिए, लेकिन यह बात नहीं है। और मुझे वास्तव में "नया अपनाने" के बारे में आपका क्या मतलब नहीं है (मुझे लगता है कि आप एक नया उदाहरण बनाना चाहते हैं), जिसे वह भी नहीं चाहता या करने की ज़रूरत नहीं है। मानचित्र सलाह के लिए – Jorn

+0

+1। –

+0

जोर्न की टिप्पणियों के बारे में .. मैंने कहा था कि यह वह जवाब है जिसे वह ढूंढ रहा है। लेखक ने कहा कि यह काम नहीं करता है, टीपीडीआई बताता है कि यह क्यों काम नहीं करता है। नया कुत्ता उदाहरण बनाने के बारे में आपकी टिप्पणी परेशान है। टीपीडीआई यह समझा रहा है कि यह आवश्यक नहीं है जैसे कि आप –

13

आपको पूरे सरणी के माध्यम से लूप करना है, इसमें कोई बदलाव नहीं है। आप तथापि, यह थोड़ा आसान कर सकते हैं

for (Dog dog : list) { 
    if (dog.getId() == id) { 
    return dog; //gotcha! 
    } 
} 
return null; // dog not found. 

या पाश के लिए नए बिना

for (int i = 0; i < list.size(); i++) { 
    if (list.get(i).getId() == id) { 
    return list.get(i); 
    } 
} 
+0

आपको सूची के माध्यम से लूप करने की आवश्यकता नहीं है। – Jon

+0

जॉन का अधिकार, लेकिन फिर भी सबसे अच्छा/साफ समाधान देने के लिए +1 जो अभी भी एक सूची का उपयोग करता है (और नक्शा नहीं)। –

+0

आपको मानचित्र को पहले स्थान पर बनाने के लिए अभी भी सूची के माध्यम से लूप करना होगा। चाहे वह अधिक कुशल हो या नहीं, कई कारकों पर निर्भर करता है, जिसमें सूची कितनी बार बदलती है और आपको कितनी बार लुकअप की आवश्यकता होती है। – Jorn

16

आपरेशन के प्रदर्शन में सुधार करने के लिए, यदि आप हमेशा कुछ लोगों द्वारा वस्तुओं को देखने के लिए चाहते करने जा रहे हैं अद्वितीय पहचानकर्ता, तो आप Map<Integer,Dog> का उपयोग करने पर विचार कर सकते हैं। यह कुंजी द्वारा निरंतर समय लुकअप प्रदान करेगा। आप अभी भी मानचित्र values() का उपयोग कर ऑब्जेक्ट्स पर फिर से सक्रिय हो सकते हैं।

आप प्राप्त करने के लिए एक त्वरित कोड टुकड़ा शुरू कर दिया:

// Populate the map 
Map<Integer,Dog> dogs = new HashMap<Integer,Dog>(); 
for(Dog dog : /* dog source */) { 
    dogs.put(dog.getId(), dog); 
} 

// Perform a lookup 
Dog dog = dogs.get(id); 

यह थोड़ा गति चीजों में मदद मिलेगी अगर आप इस सूची में एक ही प्रकृति के कई लुकअप प्रदर्शन कर रहे हैं। यदि आप सिर्फ एक लुकअप कर रहे हैं, तो आप एक ही लूप ओवरहेड को ध्यान में रखते हुए जा रहे हैं।

1

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

मुझे एक इटरेटर का उपयोग करना चाहिए था। दुर्भाग्य से java.util.Iterator प्राप्त विधि में दुष्प्रभाव है। i!=dogs.length() अभिव्यक्ति के दोहराव (मैं अपने अपवाद असर की वजह से Iterator डिजाइन पसंद नहीं है।)

private Dog findDog(int id) { 
    int i = 0; 
    for (; i!=dogs.length() && dogs.get(i).getID()!=id; ++i) { 
     ; 
    } 

    return i!=dogs.length() ? dogs.get(i) : null; 
} 

नोट (dogs.get(i).getID()!=id चुन सकते थे)।

43

मान लीजिए कि आपने कुत्ते के लिए एक समान विधि सही तरीके से लिखा है कि कुत्ते की आईडी के आधार पर तुलना सूची में किसी आइटम को वापस करने का सबसे आसान और सरल तरीका निम्नानुसार है।

if (dogList.contains(dog)) { 
    return dogList.get(dogList.indexOf(dog)); 
} 

यह कम प्रदर्शन गहन है कि यहां अन्य दृष्टिकोण हैं। इस मामले में आपको बिल्कुल एक लूप की आवश्यकता नहीं है। उम्मीद है की यह मदद करेगा।

पी।एस आप एक साधारण कुत्ते के लिए विधि के बराबर होती है इस प्रकार लिखने के लिए अपाचे कॉमन्स लैंग का उपयोग कर सकते हैं:

@Override 
public boolean equals(Object obj) {  
    EqualsBuilder builder = new EqualsBuilder().append(this.getId(), obj.getId());    
    return builder.isEquals(); 
} 
0

आप एक विशेषता है जो आईडी नहीं है पाने के लिए है। मैं CollectionUtils का उपयोग करूंगा।

Dog someDog = new Dog(); 
Dog dog = CollectionUtils(dogList, new Predicate() { 

@Override 
public boolean evaluate(Object o) 
{ 
    Dog d = (Dog)o; 
    return someDog.getName().equals(d.getName()); 
} 
}); 
0

मैं इस का उपयोग कर जावा 8 lambdas

int dogId = 2; 

return dogList.stream().filter(dog-> dogId == dog.getId()).collect(Collectors.toList()).get(0); 
संबंधित मुद्दे