JavaRush /Java блогы /Random-KK /new ArrayList(????) қалай және қай жерде инициализациялау...
Vovan
Деңгей

new ArrayList(????) қалай және қай жерде инициализациялау жақсы

Топта жарияланған
Коллекциялар шеңберін пайдаланбай codeты жазу ақылсыз болар еді. Бұл көптеген ұқыпты шешімдері бар Java-ның тамаша бөлігі. Ең бастысы, массивтерден айырмашылығы, өлшемдер туралы алаңдамаудың қажеті жоқ. ArrayList жады таусылғанша өседі. Әзірлеуші ​​бастапқы өлшем және ArrayIndexOutOfBoundsException қатесі туралы алаңдамауы керек . Бірақ жад көлемін бақылау шарты болса ше? Жинақтармен жұмыс істегенде жадты тиімді пайдалана аламыз ба?
Стандартты сұрақ туындайды: тізімді қалай инициализациялау керек? Төмендегі code жұмыс істемейді: Бұл компиляция қатесіне әкеледі: Жергілікті айнымалы атаулар инициализацияланбаған болуы мүмкін . Java спецификациясы барлық жергілікті айнымалыларды (стекте барлар) сәйкес мәндермен инициализациялауды талап етеді. Сіз мұны осылай жасай аласыз: Сөзсіз, тізімді инициализациялау керек. Тізімді бірінші жолда жасауға болады, не ақылдырақ әрекет жасап, getAllNames() әдісіндегідей жалқау инициализацияны қолдануға болады . Бұл жағдайда тізім тек қажет болғанда жасалады - егер бастапқы шарттар орындалмаса, тізім ешқашан үймеде пайда болмайды. Міне, біз негізгі сұраққа келеміз: тізімге қандай өлшемді орнату керек? Ең жақсы нұсқа - оған нақты өлшемді беру. Мысалы: Бұл жағдайда дәл n атау қайтарылуы керек және нәтижесінде n элементтен тұратын топтама жасалады. Алайда n -дің нақты мәні әрқашан белгілі бола бермейді. Тіпті келтірілген мысалда n=1000 және тек 100 атау болса ше? Коллекциялармен жұмыс істеу кезінде ең танымал әдіс әдепкі конструкторды шақыру болып табылады. Егер сіз Java бастапқы codeын қарасаңыз (1.6 нұсқасы) Көріп отырғаныңыздай, әдепкі бойынша 10 элементтен тұратын тізім жасалады . Яғни, біз тізімде 10 элементтен артық сақтауды жоспарламаған кезде әдепкі конструкторды қауіпсіз пайдалана аламыз. 11-ші элементті қосуға әрекеттенсеңіз не болады? Ешқандай жаман ештеңе жоқ... элемент сәтті қосылады. Әдіске қараңыз: массив өлшемін ensureCapacity әдісі басқарады . Көлемі 1,5 есе артады . Жаңа массив жасалады және оған элементтер жылжытылады. Егер өлшемді 10-ға орнатсақ, онда 11-ші элементте:
public List getAllNames() { List names; if (/*необходимые условия выполнены*/) { names = new ArrayList (); /*заполнение списка*/ } return names; }
List names = null; List names = new ArrayList (); List names = new ArrayList (0); List names = new ArrayList (size);
public List getTopNames (int n) { List names = null; if ( /*необходимые условия выполнены*/) { names = new ArrayList (n); /*заполнение списка*/ } return names; }
names = new ArrayList ();

/** * Конструирует пустой список с указанной начальной емкостью. * * @param initialCapacity начальная емкость списка * @exception IllegalArgumentException если указанная начальная емкость отрицательна * */ public ArrayList(int initialCapacity) { super(); if (initialCapacity < 0) this.elementData = new Object[initialCapacity]; } /** * Конструирует пустой список с начальной емкостью, равной 10. */ public ArrayList() { this(10); }
public Boolean add(E e) { ensureCapacity(size + 1); //увеличивает modCount!! elementData[size++] = e; return true; } public void ensureCapacity (int minCapacity) { modCount++; int oldCapacity = elementData.length; if (minCapacity > oldCapacity) { throw new IllegalArgumentException(“Illegal Capacity: ” + initialCapacity); Object oldData[] = elementData; int newCapacity = (oldCapacity * 3) / 2 + 1; if (newCapacity < minCapacity) newCapacity = minCapacity; // minCapacity обычно ближе к размеру, так что это беспроигрышно: elementData = Arrays.copyOf(elementData, newCapacity); } }
  • өлшемі 10 * 3/2 + 1 = 16 болып өзгереді
  • келесі өсу = 16 * 3/2 + 1 = 25
  • келесі өсу = 25 * 3/2 + 1 = 39 және т.б.
100 элемент болған жағдайда, JVM бірнеше рет жаңа массив жасап, оған элементтерді көшіруі керек. Осыны ескере отырып, массивтің қажетті өлшемі туралы болжам болса, оған жақын бастапқы сыйымдылықты орнатқан дұрыс. Міне, әрекетке арналған кейбір нұсқаулар:
  1. Жинақты қажет кезде ғана жасаңыз , әйтпесе оны нөлге инициализациялаңыз немесе Collections.EMPTY_LIST пайдаланыңыз .
  2. Қажетті өлшемді нақты білсеңіз , оны жинақ конструкторында көрсетіңіз.
  3. Элементтер саны 10 аспайтынына сенімді болсаңыз , әдепкі конструкторды пайдаланыңыз.
  4. Нөлдік өлшемді жинақты құрумен байланысты тәуекел жаңа массивтерді жасау және деректерді көшіру жиілігі жоғары болуы мүмкін. Нөлдік өлшемді жинақтарды пайдаланудың пайдасы шынымен соншалықты керемет пе, соны мұқият ойластыру керек .
  5. Әдістің басында жинақты тым үлкен инициализациялаған болсаңыз және оны азайтқыңыз келсе, trimToSize() әдісі бар .
Әрине, бұл нұсқаулар массив негізіндегі жинақтармен жұмыс істеу кезінде қолданылады және олардың ешқайсысы байланыстырылған тізім жағдайында мағынасы жоқ. Шын мәнінде, бұл проблемалар бағдарламаның өлтірулері екіталай, бірақ аздап жақсырақ жасауға мүмкіндік болса, неге оны қолданбасқа. Басқа пайдалы кеңестеріңіз бар ма? Сіз істерді жақсартудың жолдарын таптыңыз ба? Әлде мұның бәрі қажет емес пе? Сіз қалай ойлайсыз?
Пікірлер
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION