2015-09-13 3 views
7

यह सवाल मुझे समय के लिए संघर्ष कर रहा है। कभी-कभी एंड्रॉइड स्टूडियो मुझे लूप के बजाय प्रत्येक के लिए उपयोग करने के लिए क्यों चाहता है, क्योंकि जब मैं फॉर लूप का उपयोग करता हूं, तो मुझे एक चेतावनी मिलती है कि मैं प्रत्येक के लिए उपयोग कर सकता हूं (और Alt + Enter के साथ यह मुझे ऑटो टच सुझाता है)।एंड्रॉइड स्टूडियो मुझे लूप के बजाय प्रत्येक के लिए क्यों उपयोग करना चाहता है?

उदाहरण के लिए की हम इस कोड

String a = ""; 
String[] array = {"A","B","C"}; 

for(int i = 0; i < array.length; i++) { 
    a += array[i]; 
    a += ","; 
} 

है मैं एक चेतावनी

और यह सुधार एंड्रॉयड स्टूडियो

for (String anArray : array) { 
     a += anArray; 
     a += ","; 
} 

यह अधिक performant है द्वारा सुझाव दिया है मिल लगता है? वास्तव में केवल लूप के लिए उपयोग करने के लिए मुझे चेतावनी चेतावनी मिलनी चाहिए?

या जब यह लूप के लिए या प्रत्येक के लिए बेहतर है?

उत्तर

24
किताब से

: प्रभावी जावा (2 संस्करण) यहोशू बलोच द्वारा

के लिए-प्रत्येक पाश, रिलीज 1.5 में शुरू की, अव्यवस्था और इटरेटर या सूचकांक छुपा कर त्रुटि के लिए अवसर से छुटकारा मिलता है परिवर्तनीय पूरी तरह से। जिसके परिणामस्वरूप मुहावरा समान रूप से करने के लिए संग्रह और सरणियों लागू होता है: "। में"

// The preferred idiom for iterating over collections and arrays 
    for (Element e : elements) { 
     doSomething(e); 
    } 

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


यहाँ http://developer.android.com/training/articles/perf-tips.html#Loops से एक तुलना है:

static class Foo { 
    int mSplat; 
} 

Foo[] mArray = ... 

public void zero() { 
    int sum = 0; 
    for (int i = 0; i < mArray.length; ++i) { 
     sum += mArray[i].mSplat; 
    } 
} 

public void one() { 
    int sum = 0; 
    Foo[] localArray = mArray; 
    int len = localArray.length; 

    for (int i = 0; i < len; ++i) { 
     sum += localArray[i].mSplat; 
    } 
} 

public void two() { 
    int sum = 0; 
    for (Foo a : mArray) { 
     sum += a.mSplat; 
    } 
} 

zero() धीमी है, क्योंकि JIT अभी तक हर यात्रा के लिए एक बार सरणी लंबाई हो रही की लागत दूर अनुकूलित नहीं कर सकते लूप के माध्यम से।

one() तेज है। यह सब कुछ स्थानीय चरों में खींचता है, लुकअप से परहेज करता है। केवल सरणी लंबाई एक प्रदर्शन लाभ प्रदान करता है।

two() एक JIT बिना उपकरणों के लिए सबसे तेजी से है, और one() एक JIT साथ उपकरणों के लिए से पृथक। यह जावा प्रोग्रामिंग भाषा के संस्करण 1.5 में पेश किए गए लूप सिंटैक्स के लिए बढ़ाया गया है।

तो, आप डिफ़ॉल्ट रूप से पाश के लिए बढ़ाया का उपयोग करना चाहिए, लेकिन प्रदर्शन के लिए महत्वपूर्ण ArrayList यात्रा के लिए एक हाथ से लिखा गिना पाश पर विचार करें।

1

यह केवल और अधिक पठनीय है जब आप आगे या पिछड़े बिना देखे जाते हैं। खैर, यह पढ़ने योग्य है यदि आप एक अच्छा चर नाम चुनते हैं (anArray के विपरीत String: डी) के लिए। यह थोड़ा सुरक्षित भी है क्योंकि यदि आप वास्तव में बेवकूफ प्रोग्रामर थे तो आप array[2 * i] लिख सकते हैं और ArrayOutOfBoundsException फेंक सकते हैं। इसके अलावा, मुझे यह पता लगाने के लिए थोड़ा अतिरंजित लगता है कि यह जावा में एक आम मुहावरे है।

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