[Java] Verschiedene Methoden, um den in List gespeicherten Wert durch iterative Verarbeitung zu ermitteln

Erste Stufe

In diesem Artikel werde ich einige Möglichkeiten vorstellen, um die iterative Verarbeitung unter Verwendung der Datenstruktur von "List" unabhängig von der Implementierung durchzuführen.

Der Inhalt des Artikels entspricht dem gesunden Menschenverstand für diejenigen, die normalerweise Java zum Programmieren verwenden. Die Zielgruppe sind daher Anfänger bis Fortgeschrittene, die gerade mit dem Erlernen von Java begonnen haben. Ich habe jedoch den Eindruck, dass es immer noch wenige Benutzer gibt, die die in JDK 1.8 am Entwicklungsstandort hinzugefügte Methode "forEach" verwenden. Daher möchte ich Sie daran erinnern, wie Sie die Methode "forEach" zu diesem Zeitpunkt verwenden. ..

Beachten Sie, dass dieser Artikel sich mit einfachen Iterationen unter Verwendung der List-Auflistung befasst, sodass wir nicht auf die "Stream-API" eingehen, die Zwischenoperationen wie "Filter" ausführt. Ich möchte die "Stream API" in einem anderen Artikel vorstellen.

Was Sie tun können, indem Sie diesen Artikel lesen

--Iterative Verarbeitung mit Listensammlung

Betriebsmethode der iterativen Hauptverarbeitung

Direktzugriff mit der Methode "get"

Seit der Einführung praktischer und effizienter Funktionen wie der Methode "erweitert für Anweisung" und der Methode "forEach" in JDK 1.8 gibt es fast keine Situation, in der die Methode "get" für die Listensammlung verwendet wird und die iterative Verarbeitung mit wahlfreiem Zugriff durchgeführt wird. Ich tat. Dieser Direktzugriff ist jedoch die grundlegendste iterative Methode, die die List-Auflistung verwendet, unabhängig von der Implementierung. Denken Sie also daran, wenn Sie mit Java programmieren.

Die grundlegende Betriebsmethode ist wie folgt.

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

public final class TestGet {

    public static void main(String[] args) {
        final List<String> testList = new ArrayList<>(3);
        testList.add("test1");
        testList.add("test2");
        testList.add("test3");

        for (int i = 0, size = testList.size(); i < size; i++) {
            //Holen Sie sich das i-te Element der Variablen (Direktzugriff)
            System.out.println(testList.get(i));
        }
    }
}

Im obigen Beispielcode implementieren wir zuerst eine Testliste, in der drei Elemente als "ArrayList" und als Testwert von "add" gespeichert werden können.

Verwenden Sie danach die Anweisung basic for und wiederholen Sie den Vorgang für die Größe der zuvor erstellten testList. Im obigen Beispielcode wird die Variable "i" jedes Mal inkrementiert, wenn sie wiederholt wird. Wie Sie im Kommentar sehen können, erfolgt die Verarbeitung von "testList.get (i)" nacheinander für die Elemente von "testList". Es wird zufällig darauf zugegriffen.

Daher wird das Ausführungsergebnis des obigen Beispielcodes wie folgt ausgegeben.

test1
test2
test3

wichtiger Punkt

Überprüfen Sie bei Verwendung des Direktzugriffs mit der Methode "get" wie im obigen Beispielcode unbedingt die Größe der Liste, auf die zugegriffen werden soll. Wenn Sie in der Methode "get" einen Index angeben, der größer als die Größe der Zielliste ist, tritt zur Laufzeit immer eine "IndexOutOfBoundsException" auf, und der Prozess schlägt fehl.

Zum Beispiel in den folgenden Fällen.

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

public final class TestIndexOutOfBoundsException {

    public static void main(String[] args) {
        final List<String> testList = new ArrayList<>();
        testList.add("test1");
        testList.add("test2");
        testList.add("test3");

        //Geben Sie einen vierten Index an, der nicht vorhanden ist
        testList.get(3);
    }
}

Wenn ich den obigen Beispielcode ausführe, erhalte ich die folgende Ausnahme:

java.lang.IndexOutOfBoundsException: Index 3 out of bounds for length 3
    at java.base/jdk.internal.util.Preconditions.outOfBounds(Preconditions.java:64)
    at java.base/jdk.internal.util.Preconditions.outOfBoundsCheckIndex(Preconditions.java:70)
    at java.base/jdk.internal.util.Preconditions.checkIndex(Preconditions.java:248)
    at java.base/java.util.Objects.checkIndex(Objects.java:373)
    at java.base/java.util.ArrayList.get(ArrayList.java:425)

Die Größe der Liste, auf die zufällig zugegriffen werden soll, kann mit der Methode "size ()" ermittelt werden, wie im Beispielcode gezeigt, der normal endet. Wenn Sie immer nur einen Datensatz aus der Datenbank basierend auf einem eindeutigen Schlüssel abrufen können, verwenden Sie die Methode "size ()", ohne die Größe der Liste zu überprüfen, z. B. "testList.get (0);" Es ist zulässig, dabei den Zielwert abzurufen.

Der wichtige Punkt ist, den zugänglichen Bereich zu klären, damit "IndexOutOfBoundsException" zur Laufzeit beim Ausführen eines Direktzugriffs nicht auftritt.

Innerhalb der Java List-Sammlung gibt es eine häufig verwendete Datenstruktur namens "LinkedList" sowie "ArrayList". Diese "LinkedList" ist ein Mechanismus, der den Kontext der gespeicherten Elemente mit einem Link enthält, sodass sie zu einer Datenstruktur wird, die zum Einfügen neuer Elemente in das Array und zum Löschen der Elemente im Array geeignet ist.

Der wahlfreie Zugriff auf "LinkedList" weist jedoch die schlechteste Leistung auf. Wenn die Anzahl der Elemente, auf die zufällig zugegriffen werden soll, ungefähr 100 beträgt, ist die Verarbeitungszeit fast dieselbe wie bei Verwendung von "ArrayList", aber mit "LinkedList" wird der zufällige Zugriff für 100.000 oder mehr große Datenmengen wiederholt. Das ist in Bezug auf die Leistung nicht realistisch.

Wenn Sie also umfangreiche Daten mit "LinkedList" durch iterative Verarbeitung verarbeiten, arbeiten Sie mit sequentiellem Zugriff wie "erweitert für Anweisung" und "forEach" -Methode, die später eingeführt wird, anstelle eines Direktzugriffs mit der Methode "get". Bitte geh.

Beiseite

Der folgende Beispielcode für den Direktzugriff wurde bereits früher eingeführt.

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

public final class TestGet {

    public static void main(String[] args) {
        final List<String> testList = new ArrayList<>(3);
        testList.add("test1");
        testList.add("test2");
        testList.add("test3");

        for (int i = 0, size = testList.size(); i < size; i++) {
            //Holen Sie sich das i-te Element der Variablen (Direktzugriff)
            System.out.println(testList.get(i));
        }
    }
}

Ich dachte, dass die for-Anweisung im obigen Beispielcode Anfängern möglicherweise nicht vertraut ist, daher werde ich eine Erklärung hinterlassen. Im obigen Beispielcode kann die for-Anweisung wie folgt geschrieben werden.

for (int i = 0; i < testList.size(); i++) {
    // do something
}

In dem zu Beginn eingeführten Beispielcode habe ich versucht, die Größe von testList zu ermitteln, indem ich den Aufruf der size () -Methode ausgeführt habe, die sich im Initialisierungsausdrucksteil im bedingten Ausdrucksteil befand.

Sie sollten jedoch vermeiden, die obige for-Anweisung zu schreiben. Da der bedingte Ausdrucksteil "i <testList.size ()" der for-Anweisung bei jeder iterativen Verarbeitung ausgeführt wird, wird im obigen Code die Methode "size ()" durch die Größe von "testList" aufgerufen. Es wird sein. Etwa 10 oder 100 haben nur geringe Auswirkungen auf die Leistung, aber selbst kleine Unterschiede können einen großen Unterschied machen.

Sie können beispielsweise überprüfen, ob die Verarbeitung des bedingten Ausdrucksteils jedes Mal mit dem folgenden Beispielcode ausgeführt wird.

public final class Main {

    public static void main(String[] args) throws Exception {
        //Stellen Sie sicher, dass der bedingte Ausdrucksteil jedes Mal ausgeführt wird
        for (int i = 0; i < 10 && saySomething(); i++) {
            // do something
        }
    }

    private static boolean saySomething() {
        System.out.println("Hello World!");
        return true;
    }
}

Das Ausführungsergebnis des obigen Beispielcodes wird wie folgt ausgegeben. Ich würde in meiner normalen Entwicklung keinen Code wie den oben beschriebenen schreiben, aber ich konnte bestätigen, dass die saySomething () -Methode des bedingten Ausdrucksteils 10 Mal ausgeführt wurde.

Hello World!
Hello World!
Hello World!
Hello World!
Hello World!
Hello World!
Hello World!
Hello World!
Hello World!
Hello World!

Aus dem oben Gesagten ist es möglich, ein schlankeres und effizienteres Programm zu schreiben, indem die Anzahl der Fälle ermittelt wird, die im Teil des bedingten Ausdrucks im Teil des Initialisierungsausdrucks verwendet werden sollen, der zu Beginn der for-Anweisung nur einmal ausgeführt wird. Dies ist eine Technik, die nicht nur auf die size () -Methode in der List-Sammlung angewendet werden kann, sondern auch auf verschiedene Situationen. Daher möchte ich, dass Menschen, die ein besseres Programm anstreben, jeden Tag daran denken.

Sequentieller Zugriff mit "erweitert für Anweisung"

Es ist schon eine Weile her, dass die "erweiterte for-Anweisung" als Java-Funktion hinzugefügt wurde, und sie ist bereits zum De-facto-Standard für die sequentielle iterative Verarbeitung von Listensammlungen geworden. Die for-Anweisung ist außerdem einfacher und effizienter als die für den Direktzugriff.

Vor der Einführung der "erweiterten for-Anweisung" wurde ein sequentieller Zugriff erreicht, indem die "Iterator" -Schnittstelle selbst implementiert wurde. Der sequentielle Zugriff mit der "Iterator" -Schnittstelle ist kompliziert und wird häufig implementiert. Er wird selten in älteren Schreibstilen verwendet. Daher werde ich ihn in diesem Artikel nicht im Detail behandeln, sondern als Wissen, bevor "Erweiterung für Anweisung" erscheint Denken Sie daran, dass ich durch die Implementierung der Iterator-Schnittstelle selbst einen sequentiellen Zugriff erzielen konnte.

Darüber hinaus tritt die Leistungsverschlechterung bei Verwendung der "IndexOutOfBoundsException" und "LinkedList", die während des Direktzugriffs mit der "get" -Methode eingeführt wurden, während des sequentiellen Zugriffs mit der "extended for-Anweisung" nicht auf.

Wenn Sie daher die "erweiterte for-Anweisung" verwenden können, wiederholen Sie den Vorgang nicht mit wahlfreiem Zugriff und versuchen Sie, den iterativen Prozess mit der "erweiterten for-Anweisung" zu schreiben.

Wenn Sie nun den Beispielcode für den wahlfreien Zugriff mit der zuvor eingeführten Methode "get" und dem sequentiellen Zugriff mit der erweiterten Anweisung "for" umschreiben, sieht dies wie folgt aus.

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

public final class TestEnhancedForStatement {

    public static void main(String[] args) {
        final List<String> testList = new ArrayList<>(3);
        testList.add("test1");
        testList.add("test2");
        testList.add("test3");

        for (String value : testList) {
            //Holen Sie sich die in testList gespeicherten Werte von Anfang an in der richtigen Reihenfolge
            System.out.println(value);
        }
    }
}

Die Methode zum Lesen der "erweiterten for-Anweisung" im obigen Beispielcode lautet wie folgt: "Rufen Sie die in" testList "gespeicherten Werte von Anfang an in der Reihenfolge" String "ab und speichern Sie sie im Variablennamen" value "." Werden. Die Grammatik ist für andere Hochsprachen wie Python und Ruby ähnlich. Wenn Sie also bereits mit anderen Hochsprachen vertraut sind, sollte es keine besonderen Schwierigkeiten geben.

Das Ausgabeergebnis der Ausführung des obigen Beispielcodes ist wie folgt.

test1
test2
test3

Sequentieller Zugriff mit der Methode "forEach"

Mit der Einführung der Funktionsschnittstelle in JDK1.8 wurde die Methode "forEach (Consumer )" zum wiederholten Bearbeiten der Listensammlung hinzugefügt. Diese Methode ist der Methode "forEach (BiConsumer <T, U>)" sehr ähnlich, die ich zuvor in meinem Artikel [^ 1] zum Durchlaufen von Kartensammlungen eingeführt habe. Es ist jetzt möglich, die sequentielle Zugriffsverarbeitung präziser und intuitiver zu schreiben als die "erweiterte for-Anweisung".

Die grundlegende Schreibmethode ist wie folgt.

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

public final class TestForEach {

    public static void main(String[] args) {
        final List<String> testList = new ArrayList<>(3);
        testList.add("test1");
        testList.add("test2");
        testList.add("test3");

        testList.forEach((value) -> {
            //Holen Sie sich die in testList gespeicherten Werte von Anfang an in der richtigen Reihenfolge
            System.out.println(value);
        });
    }
}

Der Punkt, der schwierig erscheint, ist das Argument, aber dem Argument der Methode "forEach ()" wird ein Lambda-Ausdruck übergeben, der die Funktionsschnittstelle "Consumer " implementiert. Consumer <T> ist eine funktionale Schnittstelle, die die Operation abstrahiert, nur ein Argument zu empfangen und keinen Wert zurückzugeben.

Ich werde den Lambda-Ausdruck und die Funktionsschnittstelle weglassen, da sie vom Zweck dieses Artikels abweichen. Wenn Sie jedoch die Methode forEach () in List verwenden, ist es in Ordnung, wenn Sie sich daran erinnern, wie der obige Beispielcode geschrieben wurde.

Das Ausgabeergebnis der Ausführung des obigen Beispielcodes ist wie folgt.

test1
test2
test3

wichtiger Punkt

Wie bereits in der Erläuterung der Funktionsschnittstelle erwähnt, kann die Methode "forEach" aufgrund der Eigenschaften von "Consumer " keinen Wert zurückgeben. Wenn Sie daher "false" als booleschen Wert zurückgeben möchten, wenn während der iterativen Verarbeitung von List ein Fehler festgestellt wird, sollten Sie die Anweisung "extended for" verwenden.

[^ 1]: [Java] So erhalten Sie den in Map gespeicherten Schlüssel und Wert durch iterative Verarbeitung

Recommended Posts

[Java] Verschiedene Methoden, um den in List gespeicherten Wert durch iterative Verarbeitung zu ermitteln
[Java] So erhalten Sie den Schlüssel und den Wert, die in Map gespeichert sind, durch iterative Verarbeitung
So verbinden Sie die Zeichenfolgen in der Liste durch Kommas getrennt
So erhöhen Sie den Wert von Map in einer Zeile in Java
[Java] So suchen Sie mit der Methode includes nach Werten in einem Array (oder einer Liste)
Webanwendungsstruktur nach Java und Verarbeitungsablauf in der Präsentationsschicht
Java-Referenz zum Verständnis in der Abbildung
[Verarbeitung × Java] Verwendung der Schleife
Ändern Sie die Liste <Optional <T >> in Java in Optional <Liste <T >>
[Java small story] Überwachen Sie, wann der Liste ein Wert hinzugefügt wird
[Verarbeitung × Java] Verwendung der Klasse
So erhalten Sie das Datum mit Java
[Verarbeitung × Java] Verwendung der Funktion
So erstellen Sie Ihre eigene Anmerkung in Java und erhalten den Wert
[Hinweis] Java: Geschwindigkeit der Verarbeitung der Liste nach Zweck
[Java] Beurteilung durch Eingabe von Zeichen in das Terminal
Ich möchte den Wert in Ruby erhalten
Java iterativer Prozess
Speichern von Dateien mit der angegebenen Erweiterung unter dem in Java angegebenen Verzeichnis in der Liste
[Einführung in Java] Liste der Dinge, die am 14. Tag der Programmierung gefangen wurden
# 1_JAVA Ich möchte die Indexnummer durch Angabe eines Zeichens in der Zeichenfolge erhalten
[Java] Anzeigen der von LocalDate und DateTimeformatter erfassten Tage auf Japanisch
Einfache statistische Analyse des Geldbetrags aus der von der Mercari Java-Entwicklung durchsuchten Liste
Listenverarbeitung zum Verstehen mit Bildern --java8 stream / javaslang-
[Java] So lassen Sie den privaten Konstruktor in Lombok weg
Beispielcode zum Konvertieren von List in List <String> in Java Stream
[Java] So erhalten Sie den Maximalwert von HashMap
Quelle zum Abrufen der Umleitungsquell-URL in Java
In der Abbildung verstandene Java-Klassen und -Instanzen
Ich habe versucht, die Methode der gegenseitigen Teilung von Eugrid in Java zu implementieren
Filtern Sie die optionale Java No. 2-Liste, die im Geschäftsleben nützlich war, und erhalten Sie den ersten Wert
Verwenden Sie JLine, wenn Sie Tastenanschläge auf der Konsole zeichenweise in Java verarbeiten möchten
Verzweigungsverarbeitung mit dem Rückgabewert von RestTemplate und dem Statuscode von ResponseEntity in Spring Boot
Verschiedene Threads in Java
Java zufällig, verschiedene Verarbeitung
So erhalten Sie den Namen einer Klasse / Methode, die in Java ausgeführt wird
Verwenden Sie collection_select, um die in Active_Hash gespeicherten Daten abzurufen
[Java, Stream] Sortieren Sie die Objektliste auf Japanisch nach dem Eigenschaftsnamen
ArrayList Zeigt alles in Iterator durch iterative Verarbeitung an, während es sich im Array befindet
Einfache Möglichkeit, die Methoden- / Feldliste in Java REPL zu überprüfen
[Android, Java] Praktische Methode zur Berechnung der Differenz in Tagen
So rufen Sie den Hashwert in einem Array in Ruby ab
Erstellen Sie eine Methode, um den Steuersatz in Java zurückzugeben
Listenverarbeitung zum Verstehen mit Bildern --java8 stream / javaslang --bonus
Verschiedene Möglichkeiten zum Verketten von durch Kommas getrennten Zeichenfolgen in Java
[Rails] So zeigen Sie eine Liste der Beiträge nach Kategorie an
Denken Sie über die Unterschiede zwischen Funktionen und Methoden nach (in Java)
So leiten Sie den letzten Tag des Monats in Java ab
So wechseln Sie Java in der OpenJDK-Ära auf dem Mac
[Schienen] Anzeigen von Informationen, die in der Datenbank gespeichert sind
Ich möchte die if-else-Anweisung für bedingte Verzweigungen in Java vereinfachen
[Java] Ich möchte überprüfen, ob die Elemente in der Liste null oder leer sind. [Collection Utils]
So ändern Sie das Argument in der [Java] -Methode (für diejenigen, die durch Übergabe von Werten, Übergeben von Referenzen, Übergeben von Referenzen verwirrt sind)