JavaRush /Java блогу /Random-KY /ArrayList классынын деталдуу анализи [1-бөлүк]
Vonorim
Деңгээл

ArrayList классынын деталдуу анализи [1-бөлүк]

Группада жарыяланган
Бул макалада Collections Framework'тен ArrayList классы кеңири каралат, ал кадимки массивге негизделгендиктен, түшүнүүгө эң оңой. Сизге интервьюда бул класс жана анын Java тorнде ишке ашырылышы тууралуу суроо берилет. Экинчи бөлүктө биз калган ыкмаларды талдап, сандар үчүн динамикалык массивди өзүбүздүн ишке ашырууну жазабыз. ArrayList классы AbstractList классынан мураска алат жана төмөнкү интерфейстерди ишке ашырат: List, RandomAccess, Cloneable, Serializable. ArrayList классынын деталдуу анализи [2-бөлүк] ArrayList классынын деталдуу анализи [1-бөлүк] - 1 ArrayList классы динамикалык массивдерди колдойт, аларды зарылчылыкка жараша кеңейтүүгө болот. Анын зарылчылыгы жана эффективдүүлүгү кадимки массивдин белгиленген узундукка ээ экендиги менен түшүндүрүлөт: ал түзүлгөндөн кийин ал өсүп же кичирейе алbyte, бул массив канчалык чоңдукта керек болору белгисиз болсо, чектөөлөрдү киргизет. Негизи ArrayList классы an objectке шилтемелердин өзгөрмө узундуктагы тизме массивдери. Ички массивдин өлчөмү (уячалардын саны) андан элементтерди алып салганда автоматтык түрдө азайбай турганын түшүнүү маанилүү. sizeЧынында, массивде иш жүзүндө бар элементтердин санын көрсөткөн өзгөрмөнүн мааниси азаят. Келгиле, биз ArrayList классынын жаңы an objectин түзүп, ага 5 элементти коштук дейли. Демейки боюнча, 10 элементтен турган массив түзүлөт. Бул учурда биздин an objectтин сыйымдуулугу (көлөмү/көлөмү) 10го барабар болот, бирок өзгөрмөнүн мааниси sizeбешке барабар болот. Жана элементтерди жок кылганда биз өзгөрмөнүн маанисинин өзгөрүшүн көрөбүз size, анткени .lengthArrayList классынын ички массивине кире албай, анын узундугун биле албайбыз. Өлчөмү trimToSize()төмөндө талкууланат кошумча ыкманы колдонуу менен азайтылышы мүмкүн. Келгиле, класстык талааларды карап көрөлү.
  • Динамикалык массивдин демейки көлөмү үчүн жооптуу талаа:

    private static final int DEFAULT_CAPACITY = 10

    Жаңы an object түзүүдө жаңы ArrayList<>() (параметрлери жок конструктор) ичинде 10 элементтен турган массив түзүлөт.

  • Коллекциянын бардык элементтери сакталган талаа:

    transient Object[] elementData

    Ачкыч сөз менен белгиленген transient- стандарттуу сериялаштыруу алгоритмин колдонууда талаа byte агымына жазылbyte. Белгилей кетсек, талаа ачкыч сөз менен белгиленбеген private, бирок бул уяланган класстардан (мисалы, SubList) бул талаага кирүүнү жеңилдетүү үчүн жасалган.

  • Массивдеги элементтердин санын сактаган эсептегич талаа:

    private int size

    Кыстаруу жана жок кылуу сыяктуу операцияларды аткарууда маани көбөйөт/кемилет.

Класста дагы 3 талаа бар, бирок алар кошумча болуп саналат, ошондуктан аларды карап чыгуунун кереги жок. Класста үч конструктор бар:
  1. public ArrayList()– 10 элементтен турган бош тизме массивин түзөт;
  2. public ArrayList(Collection < ? extends E > c)– өткөн коллекциянын элементтери менен инициализацияланган тизме массивин түзөт (эгерде биз кандайдыр бир коллекциянын негизинде жаңы ArrayList түзгүбүз келсе);
  3. public ArrayList(int initialCapacity)– баштапкы сыйымдуулугу бар тизме массивди түзөт. Өткөрүлгөн initialCapacity параметри 0дөн чоң болсо, анда көрсөтүлгөн өлчөмдөгү массив түзүлөт (ички талаа elementDataга Объекттин initialCapacity өлчөмүндөгү жаңы массивге шилтеме ыйгарылган). Эгерде параметр 0 болсо, анда бош массив түзүлөт. Эгерде көрсөтүлгөн параметр 0дөн аз болсо, анда IllegalArgumentException ыргытылат.
Объект түзүү
List < String> list = new ArrayList<>();
Жаңы түзүлгөн an object listкасиеттерди (талааларды) elementDataжана size. Наркылар сактагыч elementData- бул белгилүү бир типтеги массивден башка эч нерсе эмес (жалпы түрүндө көрсөтүлгөн <>), биздин учурда String[]. Эгер параметрлери жок конструктор чакырылса, демейки боюнча Object түрүндөгү 10 элементтен турган массив түзүлөт (албетте, түргө чыгаруу менен). ArrayList классынын деталдуу анализи [1-бөлүк] - 2Элементтерди кошуу Тизме массивине элементтерди классикалык түрдө кошуу add().
public boolean add(E элемент)
Келгиле, кошумчалайлы: list.add("0"); ArrayList классынын деталдуу анализи [1-бөлүк] - 3Бул ыкманын ичинде методдун ашыкча жүктөлгөн versionсы add()деп белгиленген private, ал өз кезегинде киргизүү катары үч параметрди алат: кошула турган элемент, ички массив жана анын өлчөмү. Жеке ыкмада текшерүү пайда болот: эгерде өткөн өлчөм параметри ички массивдин узундугуна барабар болсо (б.а. массив толгон), анда массивге методдун натыйжасы ( grow(int minCapacity)талаанын учурдагы мааниси) ыйгарылат. size + 1 ыкмасына өтөт, анткени кошулуп жаткан элементти эске алуу керек), мында ички массивге баштапкы массивдин элементтерин көчүрүү менен алынган жаңы түзүлгөн массивге шилтеме ыйгарылат:
Arrays.copyOf(elementData, newCapacity(minCapacity))
Методдун экинчи параметри катары copyOfбиз методдун натыйжасын көрсөтөбүз newCapacity(int minCapacity), анын ичинде жаңы массивдин өлчөмү эсептелинет. Ал төмөнкү формуланын жардамы менен эсептелет: int newCapacity = oldCapacity + (oldCapacity >> 1) Демейки өлчөмү бар массив үчүн төмөндөгүлөр туура болот: >> 1– бит боюнча оңго бирден жылдыруу (санды жарымына чейин азайтуучу оператор). Негизи 2ге 1дин даражасына бөлүү дегенди билдирет. Көрсө, 10ду 2ге бөлүп, 10ду кошобуз. Бардыгы болуп массивдин жаңы сыйымдуулугу 15ти түзөт, бирок биз 11-элементти кошуп жаткандыктан, 15+1 болот. = 16. Келгиле, тизмебизге кайрылып көрөлү жана ага 10 элементти кошуп койдук дейли жана 11 кошууга аракет кылабыз. Текшерүү массивде бош орун жок экенин көрсөтөт. Ушуга ылайык, жаңы массив түзүлөт жана деп аталат Arrays.copyOf, ал ички системанын ыкмасын колдонот System.arraycopy(). ArrayList классынын деталдуу анализи [1-бөлүк] - 4ArrayList классынын деталдуу анализи [1-бөлүк] - 5Же JavaRush боюнча бир макаладан айкын мисал: ArrayList классынын деталдуу анализи [1-бөлүк] - 6Бардык текшерүүлөрдөн кийин жана зарыл болсо массивдин өлчөмүн көбөйтүүдөн кийин, купуя ыкмада add()массивдин аягына жаңы элемент кошулуп, учурдагы параметр sizeбирге көбөйөт. . Кийинчерээк эски массив таштанды жыйноочу тарабынан иштетилет. Динамикалык массив ушундайча иштейт: элементтерди кошкондо, анда дагы эле орун бар же жок экенин текшеребиз. Эгерде боштук бар болсо, анда биз жөн гана элементти массивдин аягына кошобуз. Аягы массивдеги акыркы уячаны эмес, маанисине туура келген уячаны билдирет size. Биринчи элементти массивге коштук, ал [0] индекси бар уячага жайгаштырылды. Талаанын мааниси sizeбирге көбөйдү жана = 1. Биз кийинки элементти кошобуз: көрүп жатабыз size = 1, ошого жараша элементти индекси [1] менен уячага жайгаштырабыз жана башкалар. Методдун эки параметр менен жүктөлгөн versionсы бар:
public void add(int index, E element)
Биз элементти кошууну каалаган уячанын ордун (индекс) көрсөтө алабыз. Биринчиден, көрсөтүлгөн индекстин маанисинин тууралыгы текшерилет, анткени туура эмес индекс көрсөтүлүшү мүмкүн, ал эч нерсе жок же жөн эле жок уячаны көрсөтөт. Индекстерди текшерүү: index > size || index < 0– эгерде көрсөтүлгөн индекс массивдин учурдагы өлчөмүнөн чоңураак болсо же ал 0дөн аз болсо, анда өзгөчө жагдай чыгарылат IndexOutOfBoundsException. Андан кийин, зарыл болсо, массивдин өлчөмү жогорудагы мисалга окшош көбөйтүлөт. Массивде кошуу/чыгаруу операциялары учурунда бир нерсе бир жерге (оңго же солго) жылдырылат деп уккандырсыз. Ошентип, жылдыруу массивди көчүрүү аркылуу ишке ашырылат: System.arraycopy(elementData, index, elementData, index + 1, s - index); Көрсөтүлгөн индекстин оң жагында жайгашкан бардык элементтер бир позицияга оңго жылдырылат (индекс+1). Ошондон кийин гана жаңы элемент көрсөтүлгөн индексте ички массивге кошулат. Биз массивдин бир бөлүгүн бирден оңго жылдыргандыктан (жаңы массив түзүлгөн эмес), бизге керектүү уяча жазуу үчүн бош болот. Эски массивдин шилтемеси өчүрүлүп, келечекте аны таштанды жыйноочу кабыл алат. "Maserati" мурунтан эле ээлеген [3] уячасына чаптаңыз:
ArrayList классынын деталдуу анализи [1-бөлүк] - 7
Ошентип, индекске элемент киргизилгенде жана массивде бош орундар жок болгондо, чакыруу System.arraycopy()эки жолу кайталанат: биринчиси -де grow(), экинчиси - методдун өзүндө add(index, value), бул бүтүндөй кошуу операциясынын ылдамдыгына айкын таасир этет. Натыйжада, ички массивге башка элементти жазуу керек болгондо, бирок ал жерде бош орун жок болсо, анда ArrayList ичинде мындай болот:
  • Жаңы массив түпнускасынан 1,5 эсе чоңураак жана бир элемент менен түзүлөт.
  • Эски массивдин бардык элементтери жаңы массивге көчүрүлөт
  • Жаңы массив ArrayList an objectинин ички өзгөрмөсүндө сакталат, ал эми эски массив таштанды деп жарыяланды.
ArrayList тибиндеги an objectтердин сыйымдуулугу төмөнкү ыкманы колдонуу менен кол менен көбөйтүлүшү мүмкүн:
public void ensureCapacity(int minCapacity)
Массивдин сыйымдуулугун алдын ала көбөйтүү менен, сиз кийинчерээк RAMдын кошумча бөлүштүрүлүшүнөн кача аласыз. Метод ички массивдин өлчөмүн көбөйтүп, ага өткөрүлүүчү элементтердин санын түзөт minCapacity. Метод ensureCapacity()талаага таасир этпейт size, ал capacityички массивдин (өлчөмүнө) таасир этет. Дагы бир жолу баса белгилейм, sizeэкөө тең capacityбашка нерселер жана аларды чаташтырбоо абдан маанилүү! Эгерде сиз ArrayList курулган негизги массивдин өлчөмүн чындап сакталган элементтердин учурдагы санына чейин азайткыңыз келсе, анда trimToSize(). Коллекциядан элементтерди алып салгандан кийин, size()ал иш жүзүндө бар элементтердин санын көрсөтөт жана capacityазайbyte! Айталы: биз 100 элементти киргиздик, биринчи 50нү жок кылдык, sizeал 50гө барабар болуп калат, ошентип capacityал 100 бойдон кала берет. Ал эми кыскартуу үчүн жана capacity, биз ыкманы колдонушубуз керек trimToSize(), ал биздин бүт мүмкүнчүлүктөрүбүздү учурдагы өлчөмгө тууралайт. Кантип туура келет? Биздин массивди эч кандай бош уячалар калбашы үчүн көчүрөт (жаңы массивдин узундугу жөн гана өлчөм талаасына барабар).
ArrayList классынын деталдуу анализи [1-бөлүк] - 8
Сиз ошондой эле биздин коллекцияга элементтерди колдонуу менен кошо аласыз addAll.
public boolean addAll(Collection< ? extends E> c)
public boolean addAll(int index, Collection< ? extends E> collection);
Биринчи параметр ыкманын параметринде көрсөтүлгөн коллекциянын бардык элементтерин (мисалы, башка барак) ыкма чакыруусу жасалган баштапкы коллекцияга (аягына кыстаруу) кошууга мүмкүндүк берет. Өткөрүлгөн коллекция (ал топтом да болушу мүмкүн) жардамы менен массивге айландырылат toArray(). Албетте, кошуу операциясы да көчүрүү аркылуу ишке ашырылат. Экинчиси - collectionиндекстен баштап тизмеге бардык элементтерди кошуу index. Бул учурда, бардык элементтер тизмедеги элементтердин саны боюнча оңго жылат collection. Элементтерди алып салуу Биринчиден, ArrayListтен элементтерди алып салуу үчүн классикалык варианттарды карап көрөлү.
public E remove(int index)
Индекс боюнча жок кылууну жүзөгө ашырат жана бардык кийинки (көрсөтүлгөн индекстеги элементтен кийин) элементтерди солго жылдырат, ошону менен "тешиктерди" жабат. Ал ошондой эле өчүрүлгөн элементти (E) кайтарып берет, ал мурда өчүрүлгөнгө чейин кошумча өзгөрмөгө жазылган, анын мааниси биз методду чакыруунун натыйжасында алабыз. E деген эмне экенин түшүнүү үчүн сиз жалпы деп аталган түрлөрү менен тааныш болушуңуз керек. E белгиси метод ArrayList an objectин түзүүдө көрсөтүлгөн маалымат түрүн кайтарып берерин көрсөтөт (эсиңизде болсун: List <String> list, тиешелүүлүгүнө жараша, бул учурда E "алмаштырылат" String). Жалпы түшүнүк үчүн, мен сизге жалпы түрлөрү менен таанышууну сунуш кылам. Киргизилген индекстин тууралыгы текшерилет, андан кийин ыкманын ичинде элемент толугу менен жок кылынbyte, бирок жеке ыкма деп аталат fastRemove(Object[] es, int i), анда жок кылуу мурунтан эле болуп турат. Биз массивибизди жана көрсөтүлгөн индексти киргизүү катары методго өткөрүп беребиз. Элементтер аркылуу көчүрүлөт System.arraycopy(), массивдин өлчөмү кичирейт, андан кийин биз акыркы элементке нөлдү дайындайбыз. Белгилеп кетсек, жаңы массив түзүлбөйт: System.arraycopy(es, i + 1, es, i, size - 1 - i); Көрсөтүлгөн индекстин (i+1) астындагы позициянын оң жагындагы бөлүгү биздин баштапкы массивге (es) көчүрүлгөн жана ал эң позициясынан баштап жайгашкан. (i) жок кылынуучу элемент жайгашкан жерде. Ошентип, биз солго жылып, элементибизди өчүрдүк.
Подробный разбор класса ArrayList [Часть 1] - 9
Төмөнкү массивден 3 индексиндеги элементти алып салууга аракет кылалы:
Подробный разбор класса ArrayList [Часть 1] - 10
Методдун экинчи versionсын карап көрөлү:
public boolean remove(Object o)
Метод тизмеден өткөн элементти o, тагыраак айтканда, көрсөтүлгөн шилтемедеги an objectти алып салат. Эгерде тизмеде элемент бар болсо, ал алынып салынат жана бардык элементтер солго жылдырылат. Эгер элемент тизмеде бар болсо жана ийгorктүү алынып салынса, ыкма чындыкты кайтарат, антпесе, жалган. Индекс боюнча өчүрүү опциясына окшоп, ыкма fastRemove()дал ошол эле аракеттерди жасаган жерде деп аталат. Айырмачылыгы, метод кошумча Object классынын remove(Object o)ыкмасы аркылуу керектүү an objectти издейт . equals()Маани боюнча алып салууда, цикл дал келүү табылганга чейин тизменин бардык элементтери аркылуу өтөт. Биринчи табылган элемент гана жок кылынат. Жыйынтыктап көрөлү: динамикалык массивден элементтерди өчүрүүдө кадимки массивдегидей тешиктер калbyte (жок кылынган уяча бош болбойт). Бардык кийинки элементтер (индекстин оң жагында болгон) бир позиция солго жылдырылат. Ар кандай деңгээлдеги тизмеден элементтерди алып салуу үчүн колдонула турган бир нече кошумча ыкмалар бар. Келгиле, аларды кыскача карап көрөлү. Биздин коллекцияны тазалоо:
public void clear()
Жөнөкөй цикл forмассивдин бардык элементтерин кайталап, ар бир элементке нөлдү дайындайт. Башка өткөрүлүп берилген коллекцияда камтылган элементтерди биздин коллекциядан алып салсаңыз болот:
public boolean removeAll(Collection< ?> c)
Эгер сиз бир нече элементтерди алып салышыңыз керек болсо, анда аны шарттуу циклде жасабашыңыз керек: бул ыкманы колдонуу ыңгайлуу жана коопсуз removeAll(). Ал тизмеден чыгарыла турган элементтердин жыйнагын кабыл алат. Коллекция максаттуу тизме сактаган түрдөгү элементтерди камтышы керек. Болбосо ыргытылат ClassCastException. Тизме методду чакыруунун натыйжасында өзгөртүлгөн болсо, метод чындыкты кайтарат.
Подробный разбор класса ArrayList [Часть 1] - 11
Өткөрүлгөн коллекцияга кирбеген элементтерди жок кылат:
public boolean retainAll(Collection< ?> c)
Подробный разбор класса ArrayList [Часть 1] - 12
Бизде коллекция бар дейли:
List< String> listFirst = new ArrayList<>();
listFirst.add("White");
listFirst.add("Black");
listFirst.add("Red");
Ал эми экинчиси:
List< String> listSecond = new ArrayList<>();
listSecond.add("Green");
listSecond.add("Red");
listSecond.add("White");
Андан кийин listSecond.retainAll(listFirst)in listSecondбойдон калат:

"White"
"Red"
"Жашыл" алынып салынгандыктан, ал listFirst. Бирок андан кийин listSecond.removeAll(listFirst)ал listSecondкалат:

"Green"
Удалorсь все элементы, которые есть в listFirst.
Өткөрүлгөн коллекцияга таандык эмес - эгерде өткөн коллекцияда жок элементтер бар болсо, анда аларды биринчиден (ыкма колдонулган) алып салуу керек дегенди билдирет. Өткөрүлгөн коллекцияга таандык - ылайык, эгерде биринчи жана экинчи (өткөрүлгөн) коллекцияларда элемент болсо, анда биринчиден дубликат жок кылынат.
protected void removeRange(int fromIndex, int toIndex)
Тизмеден башталгыч көрсөтүлгөн индекс (кошкондо) менен аягы көрсөтүлгөн индекстин (камтыган эмес) ортосундагы бардык элементтерди алып салат. Бул ыкманы түздөн-түз ArrayList an objectисинде чакыруу мүмкүн эмес экенин белгилей кетүү керек. Аны колдонуу үчүн сизден мурас керек AbstractList/ArrayList. Метод башка ыкма менен да колдонулат (субЛист, ал кийинчерээк талкууланат).
public boolean removeIf(Predicate< ? super E> filter)
Берилген предикаттын негизинде жыйнактан элементтерди алып салат. Предикаттын өзү белгилүү бир функция/алгоритм/шарт, анын негизинде берилген шартка туура келген бир же бир нече элементтер алынып салынат. Predicate— функционалдык интерфейс (бир гана ыкманы камтыйт, ошондуктан аны ламбда катары колдонсо болот), "бир параметр алынган - логикалык кайтарылган" принциби боюнча иштейт. Негизинен, ыкма интерфейстен ишке ашырууну жокко чыгарат Collectionжана төмөнкү "стратегияны" ишке ашырат: ал элементтер аркылуу айланып өтүп, биздин Predicate; андан кийин биринчи итерацияда белгиленген элементтерди алып салуу (жана жылдыруу) үчүн экинчи жолу иштетилет. PredicateКелгиле, эки an object бирдей болсо, чындыкты кайтара турган интерфейсти ишке ашыралы :
class SamplePredicate< T> implements Predicate< T>{
  T varc1;
  public boolean test(T varc){
     if(varc1.equals(varc)){
       return true;
  }
  return false;
  }
}
Башка класста ArrayList Stringжана биздин класстын an objectисин түзөлү, ал ишке ашырат Predicate:
ArrayList< String> color_list = new ArrayList<> ();
SamplePredicate< String> filter = new SamplePredicate<> ();
Келгиле, өзгөрмөгө varc1"Ак" маанисин жазалы:
filter.varc1 = "White";
Тизмеге бир нече саптарды кошолу:
color_list.add("White");
color_list.add("Black");
color_list.add("Red");
color_list.add("White");
color_list.add("Yellow");
color_list.add("White");
Тизмедеги ыкманы аткаралы removeIf, ага биз an objectибизди шарт менен өткөрүп берели:
color_list.removeIf(filter);
Натыйжада, "Ак" мааниси бар бардык саптар тизмеден алынып салынат, анткени биздин "предикат" аларды теңдик үчүн салыштырат. Акыркы тизме: [Кара, Кызыл, Сары].
Подробный разбор класса ArrayList [Часть 1] - 13
Элементтерди алмаштыруу
public E set(int index, E element)
Белгиленген позициядагы элементти indexөткөн менен алмаштырат element. Индекс ошондой эле нөлдөн чоңураак жана акыркы элементтин индексинен аз болушу керек, антпесе, өзгөчө кырдаал ыргытылат IndexOutOfBoundsException. Ички массивдин көчүрмөлөрү пайда болбойт. Жөнөкөй эле, көрсөтүлгөн индекстеги элементтин ордуна жаңы элемент киргизилет, б.а. маанисин үстүнө жаз.
Подробный разбор класса ArrayList [Часть 1] - 14
public void replaceAll(UnaryOperator<e> operator)
Коллекциянын бардык элементтерин өзгөртөт (шарт менен мүмкүн). Көбүнчө ламбдалар же анонимдүү класстар менен айкалыштырып колдонулат (бирок түшүнүктүү болуу үчүн мисалда интерфейсти ишке ашырган классты колдонобуз), ал интерфейсти ишке ашырган UnaryOperatorжана анын ыкмаларын аныктайт. Келгиле, интерфейсти ишке ашыралы:
class MyOperator< T> implements UnaryOperator< T>{
   T varc1;
   public T apply(T varc){
     return varc1;
  }
}
Башка класста ArrayList Stringжана биздин класстын an objectисин түзөлү, ал ишке ашырат UnaryOperator:
ArrayList< String> color_list = new ArrayList<> ();
MyOperator< String> operator = new MyOperator<> ();
Келгиле, өзгөрмөгө varc1"Ак" маанисин жазалы:
operator.varc1 = "White";
Тизмеге бир нече саптарды кошолу:
color_list.add("White");
color_list.add("Black");
color_list.add("Red");
color_list.add("White");
color_list.add("Yellow");
color_list.add("White");
replaceAllТизмеде an objectибизди өткөрө турган ыкманы аткаралы operator:
color_list.replaceAll(operator);
Натыйжада, тизмедеги бардык баалуулуктар "Ак" менен алмаштырылды: [Ак, Ак, Ак, Ак, Ак, Ак]. Мына ушундай жол менен, мисалы, сиз жыйнактагы саптардан бардык боштуктарды алып салсаңыз болот:
ArrayList< String> list = new ArrayList<>(Arrays.asList("A   ", "  B  ", "C"));
list.replaceAll(String::trim);
Башка ыкмалар: Сиз ArrayList тизмек массивин төмөнкү ыкманы колдонуп кадимки массивге айландырсаңыз болот:
public Object[] toArray()
же
public < T> T[] toArray(T[] a)
- бул жерде кайтарылган массивдин түрү аныкталат runtime Бул ыкма:
  1. кээ бир операцияларды тездетүү;
  2. коллекцияны түздөн-түз кабыл алуу үчүн ашыкча жүктөлбөгөн методго параметр катары массивди өткөрүү;
  3. Коллекцияга негизделген жаңы code коллекцияларды тааныбаган эски code менен интеграцияланууда.
Массивдин көчүрмө an objectисин кайтарыңыз:
public Object clone()
Сураныч, метод clone()Объекттин түрүн кайтарарын эске алыңыз, андыктан аны чакыргандан кийин керектүү класска чыгаруу керек болот. Клондоо жаңы көз карандысыз an objectти түзөт. Коллекцияда an objectтин бар-жоктугун текшериңиз:
public boolean contains(Object o)
Тизмеде an objectтин бар-жоктугун текшерет (ичинде Object классынын equals ыкмасын колдонуу, б.а. шилтемелерди салыштырат), натыйжага жараша чын/жалганды кайтарат. Кадимки циклдерден тышкары, сиз коллекцияны итерациялай аласыз (ар бир элементке кирүү, ошондой эле кандайдыр бир иш-аракеттерди аткаруу):
public void forEach(Consumer< ? super E> action)
Бул биздин тизмени көрсөтө алабыз:
List< Integer> numbers = new ArrayList<>(Arrays.asList(10, 20, 50, 100, -5));
numbers.forEach((number)-> System.out.println(number));
acceptЛамбдаларды колдонбостон, анонимдүү классты колдонуп, интерфейс ыкмасын жокко чыгарышыңыз керек Consumer:
numbers.forEach(new Consumer< Integer>() {
  @Override
   public void accept(Integer integer) {
      System.out.println(integer);
          }
});
Индекс боюнча элементти алыңыз:
public E get(int index)
Коллекция элементтерине туш келди жетүү үчүн колдонулат. Белгиленген индексте тизмеде жайгашкан элементти кайтарат. Тизмедеги элементтердин максималдуу саны index < 0же болсо , өзгөчө жагдай чыгарылат . Бул тизмеден элементти чыгаруунун негизги ыкмасы жана элементти индекс боюнча алуу убактысы ArrayListтин өлчөмүнө карабастан, ар дайым бирдей болот, анткени ал белгилүү бир массив уячасына кирип жатат. Белгиленген an objectтер үчүн индекстерди табуу: index >=IndexOutOfBoundsException
public int indexOf(Object o);
public int lastIndexOf(Object o);
Методдор тизмедеги биринчи элементтин (берилген an object биринчи жолу кездешкенде) же акыркы учурунун (берилген an object акыркы жолу кездешкенде) индексин кайтарат. Эгер элемент тизмеде жок болсо, методдор -1 кайтарат.
Подробный разбор класса ArrayList [Часть 1] - 16
Подробный разбор класса ArrayList [Часть 1] - 17
Элементтер үчүн коллекцияны текшериңиз:
public boolean isEmpty();
Тизме бош болсо, ыкма чындыкты кайтарат (талаанын барабар экендигин карап чыгат size 0), болбосо жалган. Тизме нөл элементтерди гана камтыса, метод жалганды кайтарат. Башкача айтканда, бул ыкма менен нөл элементтер да эске алынат. Тизмедеги элементтердин санын табыңыз:
public int size();
Тизмедеги элементтердин санын кайтарат (өлчөм талаасынын маанилери). Элементтердин саны тизменин сыйымдуулугунан (кубаттуулугунан) айырмаланышы мүмкүн. Тизме үчүн итераторду алыңыз:
public Iterator< E> iterator();
Кийин циклде же башка иштетүүдө колдонуу үчүн тизме үчүн итераторду кайтарат. Итератор ийгorксиз жүрүм-турумду ишке ашырат. Эгерде ал коллекцияны аралап өтүп, ага кандайдыр бир өзгөртүүлөрдү (итератор ыкмаларын колдонуу менен алынбаган) байкаса, ал дароо эле өзгөчөлүктү ыргытат ConcurrentModificationException. Итератор деп аталган нерсе бар modification count. Итератор коллекцияны ар биринен кийин кайталаганда next/hasNext/remove, бул эсептегичти текшерет. Эгерде ал итератор көрүүнү күткөн нерсеге дал келбесе, ал өзгөчө учурду жаратат. Мен бул жерде итераторлорду майда-чүйдөсүнө чейин карап отурбайм.
public ListIterator< E> listIterator() и public ListIterator< E> listIterator(int index)
Кийин циклде же башка иштетүүдө колдонуу үчүн тизме үчүн тизме итераторун кайтарат. Интерфейс тизмени эки тараптуу өтүү жана анын элементтерин өзгөртүү үчүн ListIteratorинтерфейсти кеңейтет . IteratorАшыкча жүктөлгөн versionда сиз "траверсал" баштала турган индекстен өтсөңүз болот. Бул учурда индекс метод өз ишин баштаган биринчи элементти билдирет next(), ал эми ыкма чакырылганда, previous()өтүү "өткөн индекс - 1" индексинин астындагы элементтен башталат.
public Spliterator <E> spliterator()
Java 8 бөлүүчү итератор деп аталган кеч байланыштыруучу жана катасыз тез итератордун жаңы түрүн киргизет. Бөлүүчү итераторлор элементтердин ырааттуулугун кайталоого мүмкүндүк берет, бирок алар башка жол менен колдонулат. Spliterator интерфейсинин эң маанилүү өзгөчөлүгү - анын элементтердин ырааттуулугунун айрым бөлүктөрүнүн параллелдүү итерациясын, демек, параллелдүү программалоону колдоо мүмкүнчүлүгү.
Комментарийлер
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION