Suche…


Einführung

Das Collections-Framework in java.util bietet eine Reihe generischer Klassen für Datensätze mit Funktionen, die von regulären Arrays nicht bereitgestellt werden können.

Collections Framework enthält Schnittstellen für Collection<O> mit den Haupt-Subschnittstellen List<O> und Set<O> und der Mapping-Collection Map<K,V> . Collections sind die Root-Schnittstelle und werden von vielen anderen Collection-Frameworks implementiert.

Bemerkungen

Sammlungen sind Objekte, in denen Sammlungen anderer Objekte gespeichert werden können. Sie können den Typ der in einer Sammlung gespeicherten Daten mit Generics angeben.

Sammlungen verwenden im Allgemeinen die Namespaces java.util oder java.util.concurrent .

Java SE 1.4

Java 1.4.2 und folgende unterstützen keine Generics. Daher können Sie nicht die Typparameter angeben, die eine Auflistung enthält. Abgesehen von der Typensicherheit müssen Sie auch Casts verwenden, um den korrekten Typ aus einer Sammlung zurückzuholen.

Neben Collection<E> gibt es mehrere Haupttypen von Collections, von denen einige Untertypen haben.

  • List<E> ist eine geordnete Sammlung von Objekten. Es ähnelt einem Array, definiert jedoch keine Größenbegrenzung. Implementierungen werden normalerweise intern größer, um neuen Elementen Rechnung zu tragen.
  • Set<E> ist eine Sammlung von Objekten, die keine Duplikate zulässt.
    • SortedSet<E> ist ein Set<E> , das auch die Elementreihenfolge angibt.
  • Map<K,V> ist eine Sammlung von Schlüssel / Wert-Paaren.
    • SortedMap<K,V> ist eine Map<K,V> , in der auch die Elementreihenfolge angegeben ist.
Java SE 5

Java 5 fügt einen neuen Sammlungstyp hinzu:

  • Queue<E> ist eine Sammlung von Elementen, die in einer bestimmten Reihenfolge verarbeitet werden sollen. Die Implementierung gibt an, ob dies FIFO oder LIFO ist. Dies macht die Stack Klasse überflüssig.
Java SE 6

Java 6 fügt einige neue Untertypen von Sammlungen hinzu.

  • NavigableSet<E> ist ein Set<E> mit integrierten Navigationsmethoden.
  • NavigableMap<K,V> ist eine Map<K,V> mit integrierten Navigationsmethoden.
  • Deque<E> ist eine Queue<E> , die von beiden Enden gelesen werden kann.

Beachten Sie, dass die obigen Elemente alle Schnittstellen sind. Um sie verwenden zu können, müssen Sie die entsprechenden implementierenden Klassen wie ArrayList , HashSet , HashMap oder PriorityQueue .

Für jeden Auflistungstyp gibt es mehrere Implementierungen mit unterschiedlichen Leistungskennzahlen und Anwendungsfällen.

Beachten Sie, dass das Liskov-Substitutionsprinzip für die Erfassungsuntertypen gilt. Das heißt, ein SortedSet<E> kann an eine Funktion übergeben werden, die ein Set<E> erwartet. Weitere Informationen zur Verwendung von Auflistungen mit Klassenvererbung finden Sie auch im Abschnitt Generics über Bounded Parameters .

Wenn Sie eigene Sammlungen erstellen möchten, kann es einfacher sein, eine der abstrakten Klassen (z. B. AbstractList ) zu erben, anstatt die Schnittstelle zu implementieren.

Java SE 1.2

Vor 1.2 mussten Sie stattdessen die folgenden Klassen / Schnittstellen verwenden:

  • Vector statt ArrayList
  • Dictionary anstelle von Map . Beachten Sie, dass das Wörterbuch auch eine abstrakte Klasse und keine Schnittstelle ist.
  • Hashtable statt HashMap

Diese Klassen sind veraltet und sollten in modernem Code nicht verwendet werden.

ArrayList deklarieren und Objekte hinzufügen

Wir können eine ArrayList erstellen (nach der List Schnittstelle):

List aListOfFruits = new ArrayList();
Java SE 5
List<String> aListOfFruits = new ArrayList<String>();
Java SE 7
List<String> aListOfFruits = new ArrayList<>();

Verwenden Sie nun die Methode add , um einen String hinzuzufügen:

aListOfFruits.add("Melon");
aListOfFruits.add("Strawberry");

Im obigen Beispiel enthält die ArrayList den String "Melon" an Index 0 und den String "Strawberry" an Index 1.

Wir können auch mehrere Elemente mit der addAll(Collection<? extends E> c) -Methode hinzufügen

List<String> aListOfFruitsAndVeggies = new ArrayList<String>();
aListOfFruitsAndVeggies.add("Onion");
aListOfFruitsAndVeggies.addAll(aListOfFruits);

Jetzt ist "Onion" bei aListOfFruitsAndVeggies auf 0 aListOfFruitsAndVeggies , "Melon" bei Index 1 und "Strawberry" bei Index 2.

Erstellen von Sammlungen aus vorhandenen Daten

Standardsammlungen

Java Collections-Framework

Eine einfache Methode zum Arrays.asList einer List aus einzelnen Datenwerten besteht in der Verwendung der java.utils.Arrays Methode Arrays.asList :

List<String> data = Arrays.asList("ab", "bc", "cd", "ab", "bc", "cd");

Alle Standardimplementierungsimplementierungen stellen Konstruktoren bereit, die eine andere Collection als Argument verwenden und der neuen Collection zum Zeitpunkt der Konstruktion alle Elemente hinzufügen:

List<String> list = new ArrayList<>(data); // will add data as is
Set<String> set1 = new HashSet<>(data); // will add data keeping only unique values
SortedSet<String> set2 = new TreeSet<>(data); // will add data keeping unique values and sorting
Set<String> set3 = new LinkedHashSet<>(data); // will add data keeping only unique values and preserving the original order

Google Guava Collections-Framework

Ein weiteres großartiges Framework ist Google Guava , das eine erstaunliche Google Guava ist (mit praktischen statischen Methoden) zum Erstellen verschiedener Typen von Standardsammlungen. Lists und Sets :

 import com.google.common.collect.Lists;
 import com.google.common.collect.Sets;
 ...
 List<String> list1 = Lists.newArrayList("ab", "bc", "cd");
 List<String> list2 = Lists.newArrayList(data);
 Set<String> set4 = Sets.newHashSet(data);
 SortedSet<String> set5 = Sets.newTreeSet("bc", "cd", "ab", "bc", "cd");

Mapping-Sammlungen

Java Collections-Framework

In ähnlicher Weise kann für Karten bei einer Map<String, Object> map eine neue Karte mit allen Elementen wie folgt erstellt werden:

Map<String, Object> map1 = new HashMap<>(map);
SortedMap<String, Object> map2 = new TreeMap<>(map);

Apache Commons Collections Framework

Mit Apache Commons Sie Map mit Array in ArrayUtils.toMap sowie MapUtils.toMap :

 import org.apache.commons.lang3.ArrayUtils;
 ...
 // Taken from org.apache.commons.lang.ArrayUtils#toMap JavaDoc

 // Create a Map mapping colors.
 Map colorMap = MapUtils.toMap(new String[][] {{
     {"RED", "#FF0000"},
     {"GREEN", "#00FF00"},
     {"BLUE", "#0000FF"}});

Jedes Element des Arrays muss entweder ein Map.Entry oder ein Array sein, das mindestens zwei Elemente enthält, wobei das erste Element als Schlüssel und das zweite als Wert verwendet wird.

Google Guava Collections-Framework

Dienstprogrammklasse aus dem Google Guava Framework heißt Maps :

 import com.google.common.collect.Maps;
 ...
 void howToCreateMapsMethod(Function<? super K,V> valueFunction,
           Iterable<K> keys1, 
           Set<K> keys2, 
           SortedSet<K> keys3) {
     ImmutableMap<K, V> map1 = toMap(keys1, valueFunction); // Immutable copy
     Map<K, V> map2 = asMap(keys2, valueFunction); // Live Map view
     SortedMap<K, V> map3 = toMap(keys3, valueFunction); // Live Map view
 }
Java SE 8

Stream ,

Stream.of("xyz", "abc").collect(Collectors.toList());

oder

Arrays.stream("xyz", "abc").collect(Collectors.toList());

Listen beitreten

Die folgenden Möglichkeiten können zum Verbinden von Listen verwendet werden, ohne die Quellliste (n) zu ändern.

Erste Ansatz. Hat mehr Zeilen aber leicht verständlich

List<String> newList = new ArrayList<String>();
newList.addAll(listOne);
newList.addAll(listTwo);

Zweiter Ansatz. Hat eine Zeile weniger aber weniger lesbar.

List<String> newList = new ArrayList<String>(listOne);
newList.addAll(listTwo);

Dritter Ansatz. Erfordert die Bibliothek von Drittanbieter- Apache-Commons-Collections .

ListUtils.union(listOne,listTwo);
Java SE 8

Bei Verwendung von Streams kann das gleiche durch erreicht werden

List<String> newList = Stream.concat(listOne.stream(), listTwo.stream()).collect(Collectors.toList());

Verweise. Schnittstellenliste

Elemente aus einer Liste innerhalb einer Schleife entfernen

Es ist schwierig, Elemente aus einer Liste zu entfernen, wenn sie sich innerhalb einer Schleife befinden. Dies liegt daran, dass der Index und die Länge der Liste geändert werden.

In Anbetracht der folgenden Liste werden hier einige Beispiele aufgeführt, die zu einem unerwarteten Ergebnis führen, und einige, die zu einem korrekten Ergebnis führen.

List<String> fruits = new ArrayList<String>();
fruits.add("Apple");
fruits.add("Banana");
fruits.add("Strawberry");

FALSCH

In Iteration von for Überspringen "Banane" entfernen :

Das Codebeispiel druckt nur Apple und Strawberry . Banana wird übersprungen , da es zum Index bewegt 0 einmal von Apple gelöscht wird, aber zur gleichen Zeit i zu erhöht wird 1 .

for (int i = 0; i < fruits.size(); i++) {
    System.out.println (fruits.get(i)); 
    if ("Apple".equals(fruits.get(i))) {
         fruits.remove(i);
    }     
}

Entfernen in der erweiterten for Anweisung Throws Exception:

Wegen der Iteration über die Sammlung und deren gleichzeitige Änderung.

Löst aus: java.util.ConcurrentModificationException

for (String fruit : fruits) { 
    System.out.println(fruit);
    if ("Apple".equals(fruit)) {
        fruits.remove(fruit);
    }
}

RICHTIG

While-Schleife mit einem Iterator entfernen

Iterator<String> fruitIterator = fruits.iterator();
while(fruitIterator.hasNext()) {     
    String fruit = fruitIterator.next();     
    System.out.println(fruit);
    if ("Apple".equals(fruit)) {
        fruitIterator.remove();
    } 
}

Die Iterator Schnittstelle verfügt nur für diesen Fall über eine remove() Methode. Diese Methode ist jedoch in der Dokumentation als "optional" markiert und kann eine UnsupportedOperationException .

Löst aus: UnsupportedOperationException - wenn der Entfernungsvorgang von diesem Iterator nicht unterstützt wird

Es ist daher ratsam, die Dokumentation zu überprüfen, um sicherzustellen, dass diese Operation unterstützt wird (in der Praxis, sofern es sich nicht um eine unveränderliche Sammlung handelt, die über eine Bibliothek eines Drittanbieters erhalten wird, oder wenn eine der Methoden Collections.unmodifiable...() verwendet wird. Die Operation wird fast immer unterstützt.


Während der Verwendung eines Iterator eine ConcurrentModificationException ausgelöst, wenn der modCount der List der modCount des Iterator geändert wird. Dies kann in demselben Thread oder in einer Multithread-Anwendung geschehen, die dieselbe Liste verwendet.

Ein modCount ist eine int Variable, die zählt, wie oft diese Liste strukturell geändert wurde. Eine strukturelle Änderung bedeutet im Wesentlichen, dass eine add() oder remove() Operation für das Collection Objekt aufgerufen wird (von Iterator vorgenommene Änderungen werden nicht gezählt). Wenn der Iterator erstellt wird, speichert er diesen modCount und prüft bei jeder Iteration der List , ob der aktuelle modCount ist und wann der Iterator erstellt wurde. Wenn der modCount Wert modCount wird, wird eine ConcurrentModificationException modCount .

Für die oben deklarierte Liste wird eine Operation wie folgt keine Ausnahme auslösen:

Iterator<String> fruitIterator = fruits.iterator();
fruits.set(0, "Watermelon");
while(fruitIterator.hasNext()){
    System.out.println(fruitIterator.next());
}

Iterator jedoch nach der Initialisierung eines Iterator ein neues Element zur List hinzufügen, wird eine ConcurrentModificationException :

Iterator<String> fruitIterator = fruits.iterator();
fruits.add("Watermelon");
while(fruitIterator.hasNext()){
    System.out.println(fruitIterator.next());    //ConcurrentModificationException here
}

Rückwärts iterieren

for (int i = (fruits.size() - 1); i >=0; i--) {
    System.out.println (fruits.get(i));
    if ("Apple".equals(fruits.get(i))) {
         fruits.remove(i);
    }
}

Dies überspringt nichts. Der Nachteil dieses Ansatzes ist, dass die Ausgabe umgekehrt ist. In den meisten Fällen, in denen Sie Elemente entfernen, spielt dies jedoch keine Rolle. Sie sollten dies niemals mit LinkedList tun.

Iterieren vorwärts, Anpassen des Schleifenindex

for (int i = 0; i < fruits.size(); i++) {
    System.out.println (fruits.get(i)); 
    if ("Apple".equals(fruits.get(i))) {
         fruits.remove(i);
         i--;
    }     
}

Dies überspringt nichts. Wenn das i te Element aus der List , wird das ursprünglich beim Index i+1 positionierte Element zum neuen i ten Element. Daher kann die Schleife i dekrementieren, damit die nächste Iteration das nächste Element verarbeiten kann, ohne zu überspringen.

Verwenden einer Liste "Sollte entfernt werden"

ArrayList shouldBeRemoved = new ArrayList();
for (String str : currentArrayList) {
    if (condition) {
        shouldBeRemoved.add(str);
    }
}
currentArrayList.removeAll(shouldBeRemoved);

Mit dieser Lösung kann der Entwickler überprüfen, ob die korrekten Elemente sauberer entfernt wurden.

Java SE 8

In Java 8 sind folgende Alternativen möglich. Diese sind sauberer und unkomplizierter, wenn das Entfernen nicht in einer Schleife erfolgen muss.

Stream filtern

Eine List kann gestreamt und gefiltert werden. Mit einem geeigneten Filter können Sie alle unerwünschten Elemente entfernen.

List<String> filteredList = 
    fruits.stream().filter(p -> !"Apple".equals(p)).collect(Collectors.toList());

Beachten Sie, dass im Gegensatz zu allen anderen Beispielen hier, in diesem Beispiel eine neue produziert List Instanz und hält die ursprüngliche List unverändert.

removeIf

Spart den Aufwand für das Erstellen eines Streams, wenn nur ein Satz von Elementen entfernt werden muss.

fruits.removeIf(p -> "Apple".equals(p));

Unveränderbare Sammlung

Manchmal ist es nicht ratsam, eine interne Sammlung offenzulegen, da dies aufgrund seiner veränderlichen Eigenschaft zu einer Sicherheitsanfälligkeit durch schädlichen Code führen kann. Um "schreibgeschützte" Sammlungen bereitzustellen, stellt java seine unveränderlichen Versionen zur Verfügung.

Eine nicht veränderbare Sammlung ist oft eine Kopie einer veränderbaren Sammlung, die garantiert, dass die Sammlung selbst nicht geändert werden kann. Versuche, es zu ändern, führen zu einer Ausnahme für die Ausnahme "UnsupportedOperationException".

Es ist wichtig zu beachten, dass Objekte, die sich in der Sammlung befinden, noch geändert werden können.

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class MyPojoClass {
    private List<Integer> intList = new ArrayList<>();

    public void addValueToIntList(Integer value){
        intList.add(value);
    }
    
    public List<Integer> getIntList() {
        return Collections.unmodifiableList(intList);
    }
}

Der folgende Versuch, eine nicht veränderbare Sammlung zu ändern, löst eine Ausnahme aus:

import java.util.List;

public class App {

    public static void main(String[] args) {
        MyPojoClass pojo = new MyPojoClass();
        pojo.addValueToIntList(42);
        
        List<Integer> list = pojo.getIntList();
        list.add(69);
    }
}

Ausgabe:

Exception in thread "main" java.lang.UnsupportedOperationException
    at java.util.Collections$UnmodifiableCollection.add(Collections.java:1055)
    at App.main(App.java:12)

Iteration über Sammlungen

Iteration über Liste

List<String> names  = new ArrayList<>(Arrays.asList("Clementine", "Duran", "Mike"));
Java SE 8
names.forEach(System.out::println);

Wenn wir Parallelität brauchen, verwenden Sie

names.parallelStream().forEach(System.out::println);
Java SE 5
for (String name : names) {
    System.out.println(name);
}
Java SE 5
for (int i = 0; i < names.size(); i++) {
    System.out.println(names.get(i));
}
Java SE 1.2
//Creates ListIterator which supports both forward as well as backward traversel
ListIterator<String> listIterator = names.listIterator();

//Iterates list in forward direction
while(listIterator.hasNext()){
    System.out.println(listIterator.next());
}

//Iterates list in backward direction once reaches the last element from above iterator in forward direction
while(listIterator.hasPrevious()){
    System.out.println(listIterator.previous());
}

Iteration über Set

Set<String> names = new HashSet<>(Arrays.asList("Clementine", "Duran", "Mike"));
Java SE 8
names.forEach(System.out::println);
Java SE 5
for (Iterator<String> iterator = names.iterator(); iterator.hasNext(); ) {
    System.out.println(iterator.next());
}

for (String name : names) {
    System.out.println(name);
}
Java SE 5
Iterator iterator = names.iterator();
while (iterator.hasNext()) {
    System.out.println(iterator.next());
}

Iteration über Map

Map<Integer, String> names = new HashMap<>();
names.put(1, "Clementine");
names.put(2, "Duran");
names.put(3, "Mike");
Java SE 8
names.forEach((key, value) -> System.out.println("Key: " + key + " Value: " + value));
Java SE 5
for (Map.Entry<Integer, String> entry : names.entrySet()) {
    System.out.println(entry.getKey());
    System.out.println(entry.getValue());
}
    
// Iterating over only keys
for (Integer key : names.keySet()) {
    System.out.println(key);
}
// Iterating over only values
for (String value : names.values()) {
    System.out.println(value);
}
Java SE 5
Iterator entries = names.entrySet().iterator();
while (entries.hasNext()) {
    Map.Entry entry = (Map.Entry) entries.next();
    System.out.println(entry.getKey());
    System.out.println(entry.getValue());
}

Unveränderliche leere Sammlungen

Manchmal ist es angebracht, eine unveränderliche leere Sammlung zu verwenden. Die Collections Klasse stellt Methoden bereit, um solche Sammlungen auf effiziente Weise abzurufen:

List<String> anEmptyList = Collections.emptyList();
Map<Integer, Date> anEmptyMap = Collections.emptyMap();
Set<Number> anEmptySet = Collections.emptySet();

Diese Methoden sind generisch und konvertieren die zurückgegebene Sammlung automatisch in den Typ, dem sie zugewiesen ist. Das heißt, ein Aufruf von zB emptyList() kann auf jede Art von zugeordnet werden List und ebenfalls für emptySet() und emptyMap() .

Die von diesen Methoden zurückgegebenen Auflistungen sind unveränderlich, da sie UnsupportedOperationException UnsupportedOperationException wenn Sie versuchen, Methoden aufzurufen, die ihren Inhalt ändern ( add , put usw.). Diese Auflistungen sind in erster Linie als Ersatz für leere Methodenergebnisse oder andere Standardwerte nützlich, anstatt null oder Objekte mit new erstellen.

Sammlungen und Grundwerte

Sammlungen in Java funktionieren nur für Objekte. Dh es gibt keine Map<int, int> in Java. Stattdessen müssen primitive Werte in Objekte verpackt werden, wie in der Map<Integer, Integer> . Java-Auto-Boxing ermöglicht die transparente Verwendung dieser Sammlungen:

Map<Integer, Integer> map = new HashMap<>();
map.put(1, 17); // Automatic boxing of int to Integer objects
int a = map.get(1); // Automatic unboxing.

Leider ist der Aufwand erheblich . Eine HashMap<Integer, Integer> erfordert etwa 72 Bytes pro Eintrag (z. B. bei 64-Bit-JVM mit komprimierten Zeigern und unter Annahme von Ganzzahlen größer als 256 und einer Belastung von 50% der Map). Da die tatsächlichen Daten nur 8 Byte umfassen, führt dies zu einem erheblichen Overhead. Darüber hinaus erfordert es zwei Ebenen der Indirektion (Karte -> Eintrag -> Wert), es ist unnötig langsam.

Es gibt mehrere Bibliotheken mit optimierten Sammlungen für primitive Datentypen (die nur ~ 16 Bytes pro Eintrag bei 50% Last erfordern, dh 4x weniger Speicher und eine Ebene der Dereferenzierung weniger) Werte in Java.

Übereinstimmende Elemente mit Iterator aus Listen entfernen.

Oben habe ich ein Beispiel zum Entfernen von Elementen aus einer Liste innerhalb einer Schleife bemerkt und ich dachte an ein anderes Beispiel, das diesmal mit Hilfe der Iterator Schnittstelle nützlich sein könnte.
Dies ist eine Demonstration eines Tricks, der hilfreich sein kann, wenn Sie doppelte Elemente in Listen behandeln, die Sie entfernen möchten.

Hinweis: Dies wird nur zum Entfernen von Elementen aus einer Liste innerhalb eines Schleifenbeispiels hinzugefügt:

Definieren wir also unsere Listen wie gewohnt

    String[] names = {"James","Smith","Sonny","Huckle","Berry","Finn","Allan"};
    List<String> nameList = new ArrayList<>();

    //Create a List from an Array
    nameList.addAll(Arrays.asList(names));
    
    String[] removeNames = {"Sonny","Huckle","Berry"};
    List<String> removeNameList = new ArrayList<>();

    //Create a List from an Array
    removeNameList.addAll(Arrays.asList(removeNames));

Die folgende Methode nimmt zwei Collection-Objekte auf und führt den Zauber aus, die Elemente in unserer removeNameList entfernen, die mit Elementen in nameList .

private static void removeNames(Collection<String> collection1, Collection<String> collection2) {
      //get Iterator.
    Iterator<String> iterator = collection1.iterator();
    
    //Loop while collection has items
    while(iterator.hasNext()){
        if (collection2.contains(iterator.next()))
            iterator.remove(); //remove the current Name or Item
    }
}

Aufrufen der Methode und Übergeben der nameList und der removeNameList wie folgt: removeNames(nameList,removeNameList);
Erzeugt die folgende Ausgabe:

Array-Liste vor dem Entfernen von Namen: James Smith Sonny Huckle Berry Finn Allan
Array-Liste nach dem Entfernen von Namen: James Smith Finn Allan

Eine einfache, übersichtliche Verwendung für Sammlungen, die sich als nützlich erweisen, um sich wiederholende Elemente in Listen zu entfernen.

Erstellen Sie Ihre eigene Iterable-Struktur für die Verwendung mit Iterator oder für jede Schleife.

Um sicherzustellen, dass unsere Sammlung mithilfe eines Iterators oder für jede Schleife wiederholt werden kann, müssen wir die folgenden Schritte ausführen:

  1. Das, worauf wir iterieren wollen, muss Iterable und Iterable iterator() Iterable .
  2. Entwerfen Sie einen java.util.Iterator indem Sie hasNext() , next() und remove() überschreiben.

Ich habe unten eine einfache generische Liste für verknüpfte Listen hinzugefügt, die die oben genannten Entitäten verwendet, um die verknüpfte Liste iterierbar zu machen.

package org.algorithms.linkedlist;
 
import java.util.Iterator;
import java.util.NoSuchElementException;
 
 
public class LinkedList<T> implements Iterable<T> {
 
    Node<T> head, current;
 
    private static class Node<T> {
        T data;
        Node<T> next;
 
        Node(T data) {
            this.data = data;
        }
    }
 
    public LinkedList(T data) {
        head = new Node<>(data);
    }
 
    public Iterator<T> iterator() {
        return new LinkedListIterator();
    }
 
    private class LinkedListIterator implements Iterator<T> {
 
        Node<T> node = head;
 
        @Override
        public boolean hasNext() {
            return node != null;
        }
 
        @Override
        public T next() {
            if (!hasNext())
                throw new NoSuchElementException();
            Node<T> prevNode = node;
            node = node.next;
            return prevNode.data;
        }
 
        @Override
        public void remove() {
            throw new UnsupportedOperationException("Removal logic not implemented.");
        }
    }
 
    public void add(T data) {
        Node current = head;
        while (current.next != null)
            current = current.next;
        current.next = new Node<>(data);
    }
 
}
 
class App {
    public static void main(String[] args) {
 
        LinkedList<Integer> list = new LinkedList<>(1);
        list.add(2);
        list.add(4);
        list.add(3);
 
        //Test #1
        System.out.println("using Iterator:");
        Iterator<Integer> itr = list.iterator();
        while (itr.hasNext()) {
            Integer i = itr.next();
            System.out.print(i + " ");
        }
 
        //Test #2
        System.out.println("\n\nusing for-each:");
        for (Integer data : list) {
            System.out.print(data + " ");
        }
    }
}

Ausgabe

using Iterator:
1 2 4 3
using for-each:
1 2 4 3 

Dies wird in Java 7+ ausgeführt. Sie können es auch auf Java 5 und Java 6 ausführen, indem Sie Folgendes ersetzen:

LinkedList<Integer> list = new LinkedList<>(1);

mit

LinkedList<Integer> list = new LinkedList<Integer>(1);

oder einfach jede andere Version durch Einfügen der kompatiblen Änderungen.

Pitfall: Ausnahmen für gleichzeitige Änderungen

Diese Ausnahme tritt auf, wenn eine Auflistung geändert wird, während sie mit anderen Methoden als den vom Iterator-Objekt bereitgestellten Methoden durchlaufen wird. Wir haben zum Beispiel eine Liste von Hüten und möchten alle entfernen, die über Ohrenklappen verfügen:

List<IHat> hats = new ArrayList<>();
hats.add(new Ushanka()); // that one has ear flaps
hats.add(new Fedora());
hats.add(new Sombrero());
for (IHat hat : hats) {
    if (hat.hasEarFlaps()) {
        hats.remove(hat);
    }
}

Wenn wir diesen Code ausführen, wird ConcurrentModificationException ausgelöst, da der Code die Auflistung ändert, während er durchlaufen wird. Die gleiche Ausnahme kann auftreten, wenn einer der mehreren Threads, die mit derselben Liste arbeiten, versucht, die Auflistung zu ändern, während andere iterieren. Das gleichzeitige Ändern von Sammlungen in mehreren Threads ist eine natürliche Sache, sollte jedoch mit den üblichen Werkzeugen aus der Toolbox für gleichzeitige Programmierung behandelt werden, z. B. Synchronisationssperren, spezielle Sammlungen, die für die gleichzeitige Änderung übernommen wurden, und die geklonte Sammlung von der ursprünglichen Konfiguration abändern.

Untersammlungen

Liste subList (int fromIndex, int bisIndex)

FromIndex ist hier inklusive und toIndex ist exklusiv.

List list = new ArrayList(); 
List list1 = list.subList(fromIndex,toIndex); 
  1. Wenn die Liste nicht im gegebenen Bereich vorhanden ist, wird IndexOutofBoundException ausgelöst.
  2. Alle Änderungen, die an list1 vorgenommen wurden, wirken sich auf dieselben Änderungen in der Liste aus. Dies wird als gesicherte Sammlungen bezeichnet.
  3. Wenn der fromnIndex größer ist als der toIndex (fromIndex> bisIndex), wird IllegalArgumentException ausgelöst.

Beispiel:

List<String> list = new ArrayList<String>();
List<String> list = new ArrayList<String>();
list.add("Hello1"); 
list.add("Hello2"); 
System.out.println("Before Sublist "+list); 
List<String> list2 = list.subList(0, 1);
list2.add("Hello3"); 
System.out.println("After sublist changes "+list); 

Ausgabe:
Vor der Unterliste [Hello1, Hello2]
Nach Unterlistenänderungen [Hello1, Hello3, Hello2]

Teilmenge festlegen (fromIndex, toIndex)

FromIndex ist hier inklusive und toIndex ist exklusiv.

Set set = new TreeSet(); 
Set set1 = set.subSet(fromIndex,toIndex);

Der zurückgegebene Satz löst eine IllegalArgumentException aus, wenn versucht wird, ein Element außerhalb seines Bereichs einzufügen.

Map subMap (vonKey, toKey)

fromKey ist inklusive und toKey ist exklusiv

Map map = new TreeMap();
Map map1 = map.get(fromKey,toKey);

Wenn fromKey größer als toKey ist oder wenn diese Map selbst einen eingeschränkten Bereich hat und fromKey oder toKey außerhalb der Grenzen des Bereichs liegt, wird IllegalArgumentException ausgelöst.

Alle Sammlungen unterstützen gesicherte Sammlungen, dh Änderungen, die an der Untersammlung vorgenommen wurden, haben dieselben Änderungen an der Hauptsammlung.



Modified text is an extract of the original Stack Overflow Documentation
Lizenziert unter CC BY-SA 3.0
Nicht angeschlossen an Stack Overflow