Lista - interfejs List oraz klasy ArrayList i LinkedList
Użycie prostych tablic, takich jak int[] wiąże się z wieloma ograniczeniami - np. stałym rozmiarem tablicy. Prostych tablic należy używać wyłącznie w sytuacji, gdy liczba elementów jest z góry znana i niezmienna. W każdym innym przypadku należy użyć interfejsu List, który umożliwia użycie struktur nazywanych listami.
List to rodzaj kolekcji, w której kolejność elementów jest istotna i jest utrzymywana.
Pojedynczy element może wystąpić na liście wiele razy.
package java.util.List;
public interface List<E>
extends Collection<E> // interfejs List dziedziczy od interfejsu Collection
// gdzie E to typ elementów na danej liście (w danej kolekcji)
Istnieje wiele użytecznych klas implementujących interfejs List - patrz akapit All Known Implementing Classes na stronie https://docs.oracle.com/javase/8/docs/api/java/util/List.html.
Dwie z nich - najbardziej powrzechnie używane, to:
- ArrayList - tablicowa implementacja interfejsu List - używana, gdy kluczowy jest czas dostępu do danych,
- LinkedList - wiązana implementacja interfejsu List - używana, gdy często będą wykorzystywane operacje usuwania i/lub dodawania elementów w środku listy, a kwestie szybkości wyszukiwania i dostępu do elementów będą mniej istotne. Na takiej liście każdy element "wie" gdzie znajduje się poprzedni i następny element listy.
Warto deklarować zmienną typu lista przy użyciu nazwy interfejsu List, wówczas łatwa będzie ewentualna transformacja kodu z implementacji tablicowej ArrayList na implementację wiązaną LinkedList.
Przykład:
List lista1 = new ArrayList();
List<String> listaStringów = new ArrayList<String>( 30 ); // 30 to inicjalny rozmiar listy
Kilka podstawowych metod dostępnych w klasach ArrayList oraz LinkedList:
- add( E element ); // dodaje element typu E na końcu listy; gdzie E to dowolny typ/klasa elementów - obiektów;
- add( int index, E element ); // wstaw określony element typu E na pozycję index listy; pozostała część listy ulega "przesunięciu.
- set( int index, E element ); // zastępuje element znajdujący się na określonej pozycji listy podanym elementem typu E
- remove( Object o ); // usuwa z listy pierwsze wystąpienie podanego obiektu
- remove( int index ); // usuwa element znajdujący się na pozycji index listy
- size(); // zwraca liczbę elementów na liście
- get( int index ); // pobierz element z określonej pozycji listy, nie usuwając go z listy;
- clear(); // usuwa wszystkie elementy z listy
- indexOf( Object o ); // zwraca indeks określonego obiektu
Przykład użycia listy ArrayList:
List<String> strings = new ArrayList<>();
strings.add( new String("Łańcuch-1") );
String str2 = "Łańcuch-2";
strings.add( str2 );
strings.add( "Łańcuch-3" );
System.out.println( "Number of elements at the list: " + strings.size() );
// Display each element of the list
for( String listElement : strings ) {
System.out.println( listElement );
}
// Insert new element at index 1
strings.add( 1, "NOWY_ŁAŃCUCH" );
System.out.println( "Number of elements at the list: " + strings.size() );
// Display each element of the list
for( String listElement : strings ) {
System.out.println( listElement );
}
Result:
Number of elements at the list: 3
Łańcuch-1
Łańcuch-2
Łańcuch-3
Number of elements at the list: 4
Łańcuch-1
NOWY_ŁAŃCUCH
Łańcuch-2
Łańcuch-3
Kilka przykładów dodatkowych metod dostępnych w klasie LinkedList, pozwalających na użyce listy LinkedList jako np. stosu lub kolejki:
- addFirst( E element ) // Dodaje element typu E na początku listy
- addLast( E element ) // Dodaje element typu E na końcu listy
- getFirst() // Zwraca pierwszy element listy
- getLast() // Zwraca ostatni element listy
- peekFirst() // Pobiera pierwszy element listy, ale nie usuwa go z listy. Albo zwraca wartość null, jeśli lista jest pusta.
- peekLast() // Pobiera ostatni element listy, ale nie usuwa go z listy. Albo zwraca wartość null, jeśli lista jest pusta.
- pop() // Pobiera element z listy traktowanej jak stos
- push( E element ) // Umieszcza element "na stosie"