Es ist nur ein View!
Die Methode subList
des Interfaces List
gibt im Allgemeinen keine Liste, sondern ein View auf die Originalliste zurück. Achtung: Das Verhalten kann je Implementierung variieiern.
List<Integer> list = new ArrayList<>(Arrays.asList(1, 2, 3, 4, 5));
List<Integer> subList = list.subList(1, 4);
// Ändert den zersten Eintrag der subList und damit den zweiten der Originalliste
subList.set(1, 99);
// Die Ausgangsliste wurde geändert
LOG.info(list); // Ausgabe: [1, 99, 3, 4, 5]
ConcurrentModificationException bei Strukturänderungen
Folgendes hat in einem unserer Projekte zu Problemen geführt. Wenn Änderungen an der Struktur der Original-Liste vorgenommen werden z. B. durch
add()
,remove()
oderclear()
während eine subList
existiert, wirft der Zugriff auf die subList
eine ConcurrentModificationException
.
List<Integer> list = new ArrayList<>(Arrays.asList(1, 2, 3, 4, 5));
List<Integer> subList = list.subList(1, 4);
// Strukturänderung an der Original-Liste
list.clear();
// ConcurrentModificationException beim Zugriff
subList.get(0);
Änderungen der Sublist finden sich in der Ausgangsliste
Ein subList().clear()
verändert die Ausgangsliste.
List<Integer> list = new ArrayList<>(Arrays.asList(1, 2, 3, 4, 5));
List<Integer> subList = list.subList(1, 4);
subList.clear(); // Entfernt Elemente 2, 3, 4 aus der Original-Liste
System.out.println(list); // Ausgabe: [1, 5]
Und nun?
Sublisten sollten immer an einen Konstrukktor übergeben und damit eine Kopie erzeugt werden.
List<Integer> list = new ArrayList<>(Arrays.asList(1, 2, 3, 4, 5));
// Neues Listenobjekt erzeugen, das unabhängig ist
List<Integer> subListCopy = new ArrayList<>(list.subList(1, 4));