java.util.ArrayList er en standard Java-klasse som implementerer en dynamisk liste som lar deg legge til, fjerne og finne elementer.

Java har innebygget støtte for enkle tabeller (eng: array), både for objekter (f.eks. String) og enkle datatyper (f.eks. int), men disse har svært begrenset funksjonalitet og kan bl.a. ikke endre lengde. Ved å bruke en ArrayList kan man lage dynamiske lister og manipulere innholdet med et vell av hendige metoder.

Opprette en ArrayList

En ArrayList kan instansieres som en tom liste eller ved å gi inn en annen ArrayList (egentlig et hvilken som helst Collection-objekt).

// husk import java.util.ArrayList; 
List<String> list1 = new ArrayList<String>(); // lager en ny tom liste spesialisert til å inneholde String-objekter
... fyll list1 med innhold her
List<String> list2 = new ArrayList<String>(list1); // lager en liste med samme innhold som list1

I koden over, så lager en to ArrayList-instanser, som lagres i hver sin variabel. Variablene er deklarert som List, som er grensesnittet (eng: interface) som ArrayList implementerer og som definerer alle relevante metoder. Ved å deklarere variablene som List og ikke ArrayList, så gjør vi det tydelig at vi ikke er interessert i å bruke de få ArrayList-metodene som ikke er en del av List-grensesnittet.

Som vi ser over, så angir man ved bruk av List og ArrayList hva slags type objekter man ønsker å ha i listen. Dette er strengt tatt ikke nødvendig, men det hjelper Java med å sjekke at vi bruker den riktig, f.eks. at vi putter rett type data inn i dem og at vi er forberedt på typen data som hentes ut. Eksempelvis vil en ikke kunne legg tall inn i en ArrayList<String>, kun String-objekter. Og når en tar objekter ut av lista, så vet Java at de er av typen String og vil ikke la oss tilordne dem til tall-variabler. Hvis en vil lage lister med bestemte elementer fra starten, så kan man bruke hjelpemetoden Arrays.asList:

// husk import java.util.ArrayList, java.util.List og java.util.Arrays; 
List<String> list1 = Arrays.asList("en", "to", "tre"); // lager en ny ikke-modifisertbar liste som inneholder elementene "en", "to" og "tre". Merk at denne ikke er en ArrayList
ArrayList<String> list2 = new ArrayList<String>(Arrays.asList("en", "to", "tre")); // lager en ny liste med elementene "en", "to" og "tre" (kopiert fra en ikke-modifisertbar liste)

Lister med tall og andre enkle datatyper

ArrayList kan inneholde alle typer objekter, men ikke enkle datatyper som boolean, int, double, char osv. Dette er en generell begrensning ved alle klasse som kan spesialiseres med <type>-notasjonen, og ArrayList har også denne begrensningen. Løsningen er å bruke de tilsvarende verdi-klassene Boolean, Integer, Double, Character osv. Fordi Java stort sett håndterer å blande bruk av enkle verdier og instanser av disse klassene, så er ikke ulempen så stor. F.eks. er følgende kode tillatt:

ArrayList<Integer> talliste = new ArrayList<Integer>(Arrays.asList(1, 2, 3)); // talliste fylles med elementene 1, 2 og 3
int sum012 = talliste.get(0) + talliste.get(1) + talliste.get(2); // hent ut verdier og beregn sum
talliste.add(sum012); // legg summen til som siste element i lista

Her vil Java automatisk gjøre om verdiene 1, 2 og 3 til Integer-objekter med tilsvarende verdier i, og når de tas ut, så er det verdiene inni som brukes i beregningen. Tilsvarende så konverteres summen til et Integer-objekt før det legges inn i lista.

Egenskaper ved ArrayList

ArrayList er en dynamisk liste og har metoder for å legge til på slutten av lista, legg til hvor som helst inni lista, endre enkelt-elementer og fjerne dem. Dersom man fjerner et element i midten av listen, vil de påfølgende elementene forflyttes én plass forover i listen, slik at det til enhver tid ikke er huller i listen. Følgende kodesnutt illustrerer hvordan get, add og remove-metodene virker:

List<String> list = new ArrayList<String>(Arrays.asList("A", "B", "C", "D")); // ny liste med elementene "A", "B", "C" og "D"
list.add("E");									// legg til "E" på slutten
System.out.println(list + "\n" + list.get(2));
list.remove("C"); 								// fjerne første forekomst av "C"
System.out.println(list + "\n" + list.get(2));
list.add(1, "F");								// legg til "F" på index 1 (0 er første element, 1 andre osv.)
System.out.println(list + "\n" + list.get(2));
list.add("A");									// legg til "A" på slutten
System.out.println(list + "\n" + list.get(2));
list.remove("A");								// fjern første forekomst av "A" (den som ble lagt til på slutten blir igjen)
System.out.println(list + "\n" + list.get(2));

vil skrive ut:

[A, B, C, D, E]
C
[A, B, D, E]
D
[A, F, B, D, E]
B
[A, F, B, D, E, A]
B
[F, B, D, E, A]
D

Gjennomgang (iterasjon) av liste-elementene

ArrayList har innebygget støtte for iterasjon ved hjelp av foreach-varianten av for-løkka, så der er svært enkelt å gå gjennom alle elementene i en ArrayList. Denne kodesnutten vil telle opp antall String-objekter som begynner med A:

List<String> list = ...
int count = 0;
for (String s: list) {
	if (s.startsWith("A")) {
		count = count + 1; // eller count++ eller count += 1
	}
}
// count er nå lik antall String-objekter i list som begynner med "A"

Nyttige metoder

List-grensesnittet definerer mange metoder, som ArrayList nødvendigvis implementerer. Her gir vi en kort beskrivelse av de mest brukte. Her brukes <type> for å angi typen som List-objektet er spesialisert til å håndtere.

  • void add(<type>) - legger til et element i enden av listen.
  • void add(int, <type>) - legger til et element på posisjonen angitt av argumentet.
  • void remove(Object) - fjerner den første forekomsten av argumentet hvis det finnes i listen. Elementer sammenlignes med equals-metoden.
  • int size() - returnerer størrelsen på listen, dvs. antall elementer i listen.
  • boolean contains(Object) - returnerer true hvis elementet finnes i listen, ellers false. Elementer sammenlignes med equals-metoden.
  • <type> get(int) - returnerer elementet på posisjonen angitt av argumentet.
  • void set(int,<type>) - bytter ut elementet på posisjonen angitt av det første argumentet, med det andre argumentet.
  • int indexOf(Object) - returnerer indeksen til den første forekomsten av argumentet eller -1 hvis listen ikke inneholder argumentet. Elementer sammenlignes med equals-metoden.
  • int lastIndexOf(Object) - returnerer indeksen til den siste forekomsten (eller første fra enden) av argumentet eller -1 hvis listen ikke inneholder argumentet. Elementer sammenlignes med equals-metoden.
  • boolean isEmpty() - returnerer true hvis listen ikke inneholder noen elementer, ellers false. Dette tilsvarer å sjekke om size() returnerer 0, men er mer forståelig for leseren av koden.

Typisk bruk av ArrayList

Den typiske bruken av List og ArrayList er for å implementere 1-n-assosiasjoner, dvs. at et objekt av klasse A skal kunne kobles til ett eller flere objekter av klasse B. A vil da typisk ha et felt av typen List<B> og implementere metoder som getBCount(), getB(int), addB(B) og removeB(B) som vil kalle tilsvarende metoder på ArrayList-objektet:

class A {

	private List<B> bList = new ArrayList<B>();

	public int getBCount() {
		return bList.size();
	}

	public B getB(int indeks) {
		bList.get(indeks);
	}

	public void addB(B b) {
		bList.add(b);
	}

	public void removeB(B b) {
		bList.remove(b);
	}
}