CodeGym /Java blog /Véletlen /ArrayList képekben
John Squirrels
Szint
San Francisco

ArrayList képekben

Megjelent a csoportban
Szia! A mai lecke ArrayListkönnyebb és nehezebb lesz, mint az előző leckék.
ArrayList képekben - 1
Nehezebb lesz, mert ma benézünk a motorháztető alá, ArrayListés tanulmányozzuk, mi történik a különböző műveletek során. Másrészt ennek a leckének szinte semmilyen kódja nem lesz. Leginkább képek és magyarázatok. Na, gyerünk:) Mint már tudjátok, ArrayListvan benne egy közönséges tömb, ami adattárként működik. A legtöbb esetben nem adjuk meg a lista pontos méretét. De a belső tömbnek kell lennie valami méretnek! És így is van. Az alapértelmezett mérete 10 .

public static void main(String[] args) {
   ArrayList<Car> cars = new ArrayList<>();
}
ArrayList képekben - 2 Először nézzük meg, hogyan néz ki az új elemek hozzáadása. Az első feladat annak ellenőrzése, hogy a belső tömbben van-e elég hely a belső tömbben , és hogy elfér-e még egy elem. Ha van hely, akkor az új elem a lista végére kerül. Amikor azt mondjuk, hogy "a végéig", nem a tömb utolsó pozíciójára gondolunk (ez furcsa lenne). Az utolsó aktuális elemet követő pozíciót értjük. Az indexe a következő lesz cars.size(). A listánk jelenleg üres ( cars.size() == 0). Ennek megfelelően az új elem a 0 pozícióba kerül.

ArrayList<Car> cars = new ArrayList<>();
Car ferrari = new Car("Ferrari 360 Spider");
cars.add(ferrari);
ArrayList képekben - 3 Ez elég világos. Mi történik, ha középre, azaz más elemek közé illesztjük be?

public static void main(String[] args) {
   ArrayList<Car> cars = new ArrayList<>();
   Car ferrari = new Car("Ferrari 360 Spider");
   Car bugatti = new Car("Bugatti Veyron");
   Car lambo = new Car("Lamborghini Diablo");
   Car ford = new Car("Ford Modneo");
  
   cars.add(ferrari);
   cars.add(bugatti);
   cars.add(lambo);
  
   cars.add(1, ford);// add ford to cell 1, which is already occupied
}
Ismét először meg kell vizsgálni, hogy van-e elég hely a tömbben. Ha van elég hely, akkor az elemek jobbra tolódnak el , kezdve azzal a pozícióval, ahol az új elemet beszúrjuk. Az 1. pozícióba szúrjuk be. Más szóval, a 3. pozícióból a 4. pozícióba, a 2. elem a 3. pozícióba, az 1. elem pedig a 2. pozícióba kerül átmásolásra. Ezután az ArrayList képekben - 4 új elemünk bekerül a helyére. Az előző elem (bugatti) már át lett másolva onnan egy új helyre. ArrayList képekben - 5 Most nézzük meg, hogyan történik ez a folyamat, ha nincsenek helyek, ahol új elemeket lehet beilleszteni a tömbbe. ArrayList képekben - 6 Természetesen először ellenőrizni kell, hogy van-e elég hely. Ha nincs elég hely, akkor egy új tömb jön létre benneArrayListamelynek mérete a régi tömb mérete szorozva 1,5 plusz 1 Esetünkben az új tömb mérete 16 lesz. Az összes aktuális elem azonnal oda lesz másolva. ArrayList képekben - 7 A régi tömböt a szemétgyűjtő törli, és csak az új, kibővített tömb marad meg. Most van hely egy új elemnek. A 3. pozícióba helyezzük be, ami foglalt. Most kezdődik az ismerős eljárás. Az összes elem, a 3-as indextől kezdve, egy pozícióval jobbra tolódik, és az új elem halkan hozzáadásra kerül. ArrayList képekben - 8 És kész a beillesztés! És készen is vagyunk a beillesztéssel. Most beszéljünk az elemek eltávolításáról . Emlékszel, hogy problémába ütköztünk a tömbökkel való munka során: az elemek eltávolítása "lyukakat" képez a tömbön.minden eltávolításnál, és minden alkalommal meg kellett írnunk a saját kódunkat, hogy végrehajtsuk ezt a váltást. Az ArrayList ugyanezt az elvet követi, de már megvalósítja ezt a mechanizmust. ArrayList képekben - 9 Így néz ki: ArrayList képekben - 10 És a végén megkapjuk, amit akarunk: ArrayList képekben - 11 Az lamboelemet eltávolították. Itt eltávolítottunk egy elemet a közepéről. Nyilvánvaló, hogy egy elem eltávolítása a lista végéről gyorsabb, mivel az elemet egyszerűen eltávolítják anélkül, hogy az összes többit el kellene tolni. Beszéljünk ismét egy pillanatra a belső tömb méreteiről és a memóriában való elrendezéséről. Egy tömb bővítése bizonyos erőforrásokat igényel. Ennek megfelelően ne hozzon létre egyArrayListaz alapértelmezett mérettel, ha biztos benne, hogy legalább 100 elemből áll. A belső tömböt hatszor kell bővíteni a 100. elem beszúrásáig, és az összes elemet minden alkalommal el kell tolni.
  • 10 elemtől 16-ig
  • 16 elemtől 25-ig
  • 25-től 38-ig
  • 38-tól 58-ig
  • 58-tól 88-ig
  • 88-tól 133-ig (azaz a régi tömb mérete 1,5 plusz 1)
Ahogy el tudod képzelni, ez meglehetősen erőforrás-igényes. Tehát, ha már tudja (akár hozzávetőlegesen is) a szükséges elemek számát, jobb, ha egy listát készít egy adott méretű tömbből:

ArrayList<Car> cars = new ArrayList<>(100);
Most a 100 elemből álló tömb memóriája egyszerre lesz lefoglalva, így a tömb hatékonyabb lesz (nem kell bővíteni). Ennek a stratégiának van egy másik oldala is. Ha objektumokat távolít el egy tömbből ArrayList, a belső tömb mérete nem csökken automatikusan. Tegyük fel, hogy van egy ArrayListteljesen teljes, 88 elemből álló belső tömbünk: ArrayList képekben - 12 A program futása közben 77 elemet eltávolítunk, így csak 11 marad: ArrayList képekben - 13 Kitaláltad már, mi a probléma? Érted, nem hatékony memóriahasználat! Itt csak 11 pozíciót használunk, de 88 elemhez foglaltunk memóriát. Ez 8-szor több a kelleténél! Ebben az esetben optimalizálhatjuk memóriahasználatunkat az ArrayListosztály egyik speciális metódusával:trimToSize(). Ez a módszer "levágja" a belső tömb hosszát a benne jelenleg tárolt elemek számára. ArrayList képekben - 14 Most már csak annyi memóriát foglaltunk le, amennyire szükségünk van! :)
Hozzászólások
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION