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

Java ArrayList

Megjelent a csoportban
Szia! Az előző leckéken mélyrehatóan elmélyültünk a tömbökben, és áttekintettük a tömbökkel végzett munka gyakori példáit. Ebben a leckében közelebbről áttekintjük a Java ArrayList-et. Általában a tömbök rendkívül hasznosak. És ahogy már észrevettétek, sokat lehet velük kezdeni :) De a tömböknek számos hiányossága van.
  • Korlátozott méret. Tudnia kell, hogy a tömbnek hány elemet kell tartalmaznia a létrehozáskor. Ha alábecsüli, akkor nem lesz elég hely. Túlbecsüljük, és a tömb félig üres marad, ami szintén rossz. Végül is a szükségesnél több memóriát foglal le.

  • Egy tömbben nincsenek módszerek elemek hozzáadására. Mindig kifejezetten meg kell jelölnie annak a pozíciónak az indexét, ahová elemet kíván hozzáadni. Ha véletlenül megadja az indexet egy olyan pozícióhoz, amelyet valamilyen szükséges érték foglal el, a rendszer felülírja.

  • Nincsenek módszerek az elemek törlésére. Egy érték csak "nullázható".

public class Cat {

   private String name;

   public Cat(String name) {
       this.name = name;
   }

   public static void main(String[] args) {

       Cat[] cats = new Cat[3];
       cats[0] = new Cat("Thomas");
       cats[1] = new Cat("Behemoth");
       cats[2] = new Cat("Lionel Messi");

       cats[1] = null;

      
      
       System.out.println(Arrays.toString(cats));
   }

   @Override
   public String toString() {
       return "Cat{" +
               "name='" + name + '\'' +
               '}';
   }
}
Kimenet: [Cat{name='Thomas'}, null, Cat{name='Lionel Messi'}] Szerencsére a Java készítői tisztában vannak a tömbök előnyeivel és hátrányaival, ezért létrehoztak egy igen érdekes adatstruktúrát Java ArrayList néven . A lehető legegyszerűbben szólva, a Java ArrayList egy sok új funkciót tartalmazó, "felújított" tömb.

ArrayList létrehozása

Nagyon egyszerű létrehozni:

ArrayList<Cat> cats = new ArrayList<Cat>();
Most létrehoztunk egy listát a Cat objektumok tárolására. Vegye figyelembe, hogy nem adjuk meg az ArrayList méretét , mert az automatikusan kibővülhet. Hogyan lehetséges ez? Valójában elég egyszerű. Lehet, hogy meglep, de a Java ArrayList egy nagyon hétköznapi tömbre épül :) Igen, van benne egy tömb, és ott tárolódnak az elemeink. De az ArrayList a Java-ban egy speciális módszerrel dolgozik ezzel a tömbbel:
  • Amikor a belső tömb megtelt, az ArrayList belsőleg új tömböt hoz létre. Az új tömb mérete a régi tömb méretének szorzata 1,5 plusz 1.

  • Minden adat átmásolódik a régi tömbből az újba

  • A régi tömböt a szemétgyűjtő takarítja fel.
Ez a mechanizmus lehetővé teszi a Java ArrayList-nek (a hagyományos tömböktől eltérően) új elemek hozzáadásának módszerét. Ez a add()módszer

public static void main(String[] args) {

   ArrayList<Cat> cats = new ArrayList<Cat>();
   cats.add(new Cat("Behemoth"));
}
Az új elemek a lista végére kerülnek. Most már nem áll fenn a veszély, hogy túlcsordul a tömb, így ez a módszer teljesen biztonságos. Az ArrayList egyébként nem csak az indexe alapján tud egy objektumot megtalálni, hanem fordítva is: egy hivatkozás segítségével megkeresheti egy objektum indexét az ArrayListben ! Erre szolgál az indexOf() metódus: Hivatkozást adunk át a kívánt objektumra, és az indexOf() visszaadja az indexét:

public static void main(String[] args) {

   ArrayList<Cat> cats = new ArrayList<>();
   Cat thomas = new Cat("Thomas");
   Cat behemoth = new Cat("Behemoth");
   Cat lionel = new Cat("Lionel Messi");
   Cat fluffy = new Cat ("Fluffy");

   cats.add(thomas);
   cats.add(behemoth);
   cats.add(lionel);
   cats.add(fluffy);

   int thomasIndex = cats.indexOf(thomas);
   System.out.println(thomasIndex);
}
Kimenet: 0 Így van. A thomas objektum valóban a 0. elemben van tárolva. A tömböknek nem csak hátrányai vannak. Megkérdőjelezhetetlen előnyeik is vannak. Az egyik az elemek index szerinti keresésének lehetősége. Mivel egy indexre mutatunk, azaz egy adott memóriacímre, a tömb ilyen módon történő keresése nagyon gyors. ArrayListő is tudja, hogyan kell csinálni! A get() metódus ezt valósítja meg:

public static void main(String[] args) {

   ArrayList<Cat> cats = new ArrayList<>();
   Cat thomas = new Cat("Thomas");
   Cat behemoth = new Cat("Behemoth");
   Cat lionel = new Cat("Lionel Messi");
   Cat fluffy = new Cat ("Fluffy");

   cats.add(thomas);
   cats.add(behemoth);
   cats.add(lionel);
   cats.add(fluffy);

   Cat secondCat = cats.get(1);

   System.out.println(secondCat);
}
Kimenet: Cat{name='Behemoth'} Ezenkívül könnyen megtudhatja, hogy az ArrayList tartalmaz-e egy adott objektumot. Ez az ArrayList include() metódussal történik :

public static void main(String[] args) {

   ArrayList<Cat> cats = new ArrayList<>();
   Cat thomas = new Cat("Thomas");
   Cat behemoth = new Cat("Behemoth");
   Cat lionel = new Cat("Lionel Messi");
   Cat fluffy = new Cat ("Fluffy");

   cats.add(thomas);
   cats.add(behemoth);
   cats.add(lionel);
   cats.add(fluffy);

   cats.remove(fluffy);
   System.out.println(cats.contains(fluffy));
}
A metódus ellenőrzi, hogy az ArrayList belső tömbje tartalmazza-e az elemet, és egy logikai értéket (igaz vagy hamis) ad vissza. Kimenet: hamis És még egy fontos dolog a beszúrással kapcsolatban. Az ArrayList lehetővé teszi, hogy index segítségével ne csak a tömb végére, hanem bárhová is beszúrjon elemeket. Ennek két módja van:
  • ArrayList add(int index, Cat elem)
  • ArrayList set(int index, Cat elem)
Argumentumként mindkét módszer a beszúrni kívánt pozíció indexét és magára az objektumra való hivatkozást veszi fel. A különbség az, hogy a set() használatával történő beszúrás felülírja a régi értéket. Az add() paranccsal történő beszúrás először eggyel eltolja az összes elemet [index]-ről a tömb végére, majd hozzáadja a megadott objektumot a kapott üres pozícióba.

Íme egy példa:


public static void main(String[] args) {

   ArrayList<Cat> cats = new ArrayList<>();
   Cat thomas = new Cat("Thomas");
   Cat behemoth = new Cat("Behemoth");
   Cat lionel = new Cat("Lionel Messi");
   Cat fluffy = new Cat ("Fluffy");

   cats.add(thomas);
   cats.add(behemoth);

   System.out.println(cats.toString());

   cats.set(0, lionel);// Now we have a list of 2 cats. Adding a 3rd using set

   System.out.println(cats.toString());
}
Kimenet: [[Cat{name='Thomas'}, Cat{name='Behemoth'}] [Cat{name='Lionel Messi'}, Cat{name='Behemoth'}] 2 macskát tartalmazó listánk volt . Ezután beszúrtunk egy másikat 0 elemként a set() metódussal. Ennek eredményeként a régi elemet egy új váltotta fel.

public static void main(String[] args) {

   ArrayList<Cat> cats = new ArrayList<>();
   Cat thomas = new Cat("Thomas");
   Cat behemoth = new Cat("Behemoth");
   Cat lionel = new Cat("Lionel Messi");
   Cat fluffy = new Cat ("Fluffy");

   cats.add(thomas);
   cats.add(behemoth);

   System.out.println(cats.toString());

   cats.add(0, lionel);// Now we have a list of 2 cats. Adding a 3rd using add

   System.out.println(cats.toString());
}
És itt látjuk, hogy az add() másképp működik. Az összes elemet jobbra mozgatja, majd az új értéket 0 elemként írja ki. Kimenet: [Cat{name='Thomas'}, Cat{name='Behemoth'}] [Cat{name='Lionel Messi'}, Cat{name='Thomas'}, Cat{name='Behemoth'}] A lista teljes törléséhez a clear() metódust használjuk :

public static void main(String[] args) {

   ArrayList<Cat> cats = new ArrayList<>();
   Cat thomas = new Cat("Thomas");
   Cat behemoth = new Cat("Behemoth");
   Cat lionel = new Cat("Lionel Messi");
   Cat fluffy = new Cat ("Fluffy");

   cats.add(thomas);
   cats.add(behemoth);
   cats.add(lionel);
   cats.add(fluffy);

   cats.clear();

   System.out.println(cats.toString());
}
Kimenet: [] Mindent eltávolítottak a listáról. Mellesleg vegye figyelembe: a tömböktől eltérően az ArrayList felülírja a toString() metódust, és már megfelelően karakterláncként jeleníti meg a listát. A közönséges tömböknél ehhez az Arrays osztályt kellett használnunk. És mivel már említettem a tömböket : a Java segítségével könnyedén "válthat" egy tömb és egy ArrayList között , azaz konvertálhatja az egyiket a másikba. Az Arrays osztályban erre van egy Arrays.asList() metódus. Arra használjuk, hogy a tartalmat tömbként kapjuk meg, és átadjuk az ArrayList konstruktorunknak:

public static void main(String[] args) {

   ArrayList<Cat> cats = new ArrayList<>();


   Cat thomas = new Cat("Thomas");
   Cat behemoth = new Cat("Behemoth");
   Cat lionel = new Cat("Lionel Messi");
   Cat fluffy = new Cat ("Fluffy");

   Cat[] catsArray = {thomas, behemoth, lionel, fluffy};

   ArrayList<Cat> catsList = new ArrayList<>(Arrays.asList(catsArray));
   System.out.println(catsList);
}
Kimenet: [Cat{name='Thomas'}, Cat{name='Behemoth'}, Cat{name='Lionel Messi'}, Cat{name='Fluffy'}] Az ellenkező irányba is mehetsz: get egy tömb egy ArrayList objektumból. Ezt a toArray() metódussal tesszük :

public static void main(String[] args) {

   ArrayList<Cat> cats = new ArrayList<>();

   Cat thomas = new Cat("Thomas");
   Cat behemoth = new Cat("Behemoth");
   Cat lionel = new Cat("Lionel Messi");
   Cat fluffy = new Cat ("Fluffy");

   cats.add(thomas);
   cats.add(behemoth);
   cats.add(lionel);
   cats.add(fluffy);

   Cat[] catsArray = cats.toArray(new Cat[0]);

   System.out.println(Arrays.toString(catsArray));
}
Megjegyzés: egy üres tömböt adtunk át a toArray() metódusnak. Ez nem hiba. Az ArrayList osztályon belül ez a metódus úgy van megvalósítva, hogy egy üres tömb átadása növeli a teljesítményét. Csak tartsa ezt szem előtt a jövőre nézve (természetesen átadhat egy bizonyos méretű tömböt; ez is működik). Ó, a méretről. A lista aktuális mérete a size() metódussal érhető el :

public static void main(String[] args) {

   ArrayList<Cat> cats = new ArrayList<>();


   Cat thomas = new Cat("Thomas");
   Cat behemoth = new Cat("Behemoth");
   Cat lionel = new Cat("Lionel Messi");
   Cat fluffy = new Cat ("Fluffy");

   cats.add(thomas);
   cats.add(behemoth);
   cats.add(lionel);
   cats.add(fluffy);

   System.out.println(cats.size());
}
Fontos megérteni, hogy a tömb hossza tulajdonságától eltérően az ArrayList.size() metódus az elemek tényleges számát adja vissza, nem az eredeti kapacitást. Végül is nem adtunk meg méretet az ArrayList létrehozásakor . Megadhatja azonban – az ArrayList rendelkezik megfelelő konstruktorral. Az új elemek hozzáadását illetően azonban ez nem változtat a viselkedésén:

public static void main(String[] args) {

   ArrayList<Cat> cats = new ArrayList<>(2);// create an ArrayList with an initial capacity of 2


   Cat thomas = new Cat("Thomas");
   Cat behemoth = new Cat("Behemoth");
   Cat lionel = new Cat("Lionel Messi");
   Cat fluffy = new Cat ("Fluffy");

   cats.add(thomas);
   cats.add(behemoth);
   cats.add(lionel);
   cats.add(fluffy);

   System.out.println(cats.size());
}
Konzol kimenet: 4 Létrehoztunk egy listát 2 elemből, de csendesen bővült, amikor szükség volt rá. Egy másik szempont, hogy ha kezdetben nagyon kicsi listát hozunk létre, akkor annak gyakrabban kell bővülnie, ami bizonyos erőforrásokat fog igénybe venni. Ebben a leckében alig foglalkoztunk az elemek ArrayList- ből való eltávolításának folyamatával . Természetesen ez nem azért van, mert kiesett a fejünkből. Ezt a témát egy külön leckébe helyeztük, amellyel később találkozni fog :) A tanultak megerősítése érdekében javasoljuk, hogy nézzen meg egy videóleckét a Java-tanfolyamról
Hozzászólások
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION