Heim  >  Artikel  >  Java  >  Wie verwende ich Funktionen zum Durchlaufen eines zweidimensionalen Arrays in Java?

Wie verwende ich Funktionen zum Durchlaufen eines zweidimensionalen Arrays in Java?

WBOY
WBOYnach vorne
2023-05-07 19:34:061180Durchsuche

Vorwort

Was die Array-Traversierung betrifft, so hat im Grunde jeder Entwickler darüber geschrieben. Über die Traversierung selbst gibt es nicht viel zu sagen, aber wenn wir während des Traversierungsprozesses eine komplexe Geschäftslogik haben, werden wir feststellen, dass dies die Ebene des Codes ist wird sich allmählich vertiefen.

Suchen Sie beispielsweise in einem einfachen Fall die geraden Zahlen in einem zweidimensionalen Array und speichern Sie sie in einer Liste.

Durchlaufen Sie das zweidimensionale Array und beurteilen Sie, ob es sich um eine gerade Zahl handelt kann leicht geschrieben werden, wie:

public void getEven() {
    int[][] cells = new int[][]{{1, 2, 3, 4}, {11, 12, 13, 14}, {21, 22, 23, 24}};
    List<Integer> ans = new ArrayList<>();
    for (int i = 0; i < cells.length; i ++) {
        for (int j = 0; j < cells[0].length; j++) {
            if ((cells[i][j] & 1) == 0) {
                ans.add(cells[i][j]);
            }
        }
    }
    System.out.println(ans);
}

An der obigen Implementierung ist nichts auszusetzen, aber die Tiefe dieses Codes kann leicht drei Ebenen erreichen Das zweidimensionale Array ist in Ordnung. Wenn es sich um ein dreidimensionales Array handelt, sind es mit ein wenig Logik nicht vier oder fünf Ebenen , was wird das Problem sein, wenn die Codeebenen zunehmen?

Was ist das Problem, solange der Code ausgeführt werden kann? !

1. Funktionsmethoden reduzieren die Codeebene

Da die Durchlaufebene mehrdimensionaler Arrays natürlich sehr tief ist, gibt es eine Möglichkeit, sie zu reduzieren?

Um dieses Problem zu lösen, besteht der Schlüssel darin, die Schlüsselpunkte zu erfassen. Was ist der Schlüsselpunkt der Durchquerung? Holen Sie sich die Koordinaten jedes Elements! Was können wir also tun?

Definieren Sie eine Funktionsmethode, die Eingabe sind die Funktionskoordinaten und führen Sie unsere Durchlauflogik in diesem Funktionskörper aus

Basierend auf der obigen Idee glaube ich, dass wir leicht eine allgemeine Methode zur Durchquerung zweidimensionaler Arrays schreiben können
public static void scan(int maxX, int maxY, BiConsumer<Integer, Integer> consumer) {
    for (int i = 0; i < maxX; i++) {
        for (int j = 0; j < maxY; j++) {
            consumer.accept(i, j);
        }
    }
}

Hauptsächlich für die obige Implementierung verwendet die Funktionsmethode direkt den von JDK bereitgestellten BiConsumer. Die beiden Parameter sind int-Arrays, wie in der folgenden Tabelle gezeigt. Wie wird das oben Gesagte verwendet?

Das gleiche ist das obige Beispiel. Nach der Änderung sieht es so aus:

public void getEven() {
    int[][] cells = new int[][]{{1, 2, 3, 4}, {11, 12, 13, 14}, {21, 22, 23, 24}};
    List<Integer> ans = new ArrayList<>();
    scan(cells.length, cells[0].length, (i, j) -> {
        if ((cells[i][j] & 1) == 0) {
            ans.add(cells[i][j]);
        }
    });
    System.out.println(ans);
}

Im Vergleich zum vorherigen scheint es, dass es nur eine Ebene weniger gibt, und es scheint keine große Sache zu sein Wenn das Array jedoch dreidimensional oder vierdimensional wird und keine Dimension vorhanden ist, ändert sich die Schreibebene dieser Änderung nicht. Aber wenn wir während des Durchlaufvorgangs auf eine bestimmte Bedingung stoßen, können wir direkt zurückkehren. Können Sie das unterstützen?

Wenn wir beispielsweise ein zweidimensionales Array durchlaufen und feststellen möchten, ob es gerade Zahlen darin enthält, wie können wir es dann runden?

Denken Sie sorgfältig über unsere Scan-Methode nach und hoffen Sie, die Rückgabe zu unterstützen. Das Hauptproblem besteht darin, dass ich nach der Ausführung der Funktionsmethode wissen soll, ob ich die Schleife fortsetzen oder direkt zurückkehren soll Logik Ein zusätzlicher Rückgabewert wird verwendet, um zu markieren, ob die Schleife unterbrochen und direkt zurückgegeben werden soll

Basierend auf dieser Idee können wir eine einfache Demoversion implementieren

Definieren Sie eine Funktionsmethode, die den Index der Schleife + Rückgabewert akzeptiert

@FunctionalInterface
public interface ScanProcess<T> {
    ImmutablePair<Boolean, T> accept(int i, int j);
}

Allgemeine Schleifenmethode Es kann entsprechend geändert werden:

public static <T> T scanReturn(int x, int y, ScanProcess<T> func) {
    for (int i = 0; i < x; i++) {
        for (int j = 0; j < y; j++) {
            ImmutablePair<Boolean, T> ans = func.accept(i, j);
            if (ans != null && ans.left) {
                return ans.right;
            }
        }
    }
    return null;
}

Basierend auf der obigen Idee ist unsere tatsächliche Nutzungshaltung wie folgt:

@Test
public void getEven() {
    int[][] cells = new int[][]{{1, 2, 3, 4}, {11, 12, 13, 14}, {21, 22, 23, 24}};
    List<Integer> ans = new ArrayList<>();
    scanReturn(cells.length, cells[0].length, (i, j) -> {
        if ((cells[i][j] & 1) == 0) {
            return ImmutablePair.of(true, i + "_" + j);
        }
        return ImmutablePair.of(false, null);
    });
    System.out.println(ans);
}

Die obige Implementierung kann unsere Anforderungen erfüllen. Die einzige Besonderheit ist die Rückgabe Gibt es außer dieser Methode noch eine andere Möglichkeit?

Nachdem wir nun den Rückgabewert berücksichtigt haben, wie sieht es mit der Übergabe von Parametern aus? Ist es möglich, einen definierten Parameter zu verwenden, um zu bestimmen, ob unterbrochen und das Ergebnis zurückgegeben werden soll?

Basierend auf dieser Idee können wir zunächst eine Parameterverpackungsklasse definieren:

public static class Ans<T> {
    private T ans;
    private boolean tag = false;

    public Ans<T> setAns(T ans) {
        tag = true;
        this.ans = ans;
        return this;
    }

    public T getAns() {
        return ans;
    }
}

public interface ScanFunc<T> {
    void accept(int i, int j, Ans<T> ans)
}
Wir hoffen, die Schleifenergebnisse über die Ans-Klasse aufzuzeichnen, wobei tag=true bedeutet, dass die Schleife nicht fortgesetzt und direkt zurückgegeben werden muss die ans-Ergebnisse

Die entsprechenden Methodenmodifikationen und Beispiele sind wie folgt:

public static <T> T scanReturn(int x, int y, ScanFunc<T> func) {
    Ans<T> ans = new Ans<>();
    for (int i = 0; i < x; i++) {
        for (int j = 0; j < y; j++) {
            func.accept(i, j, ans);
            if (ans.tag) {
                return ans.ans;
            }
        }
    }
    return null;
}
public void getEven() {
    int[][] cells = new int[][]{{1, 2, 3, 4}, {11, 12, 13, 14}, {21, 22, 23, 24}};
    String ans = scanReturn(cells.length, cells[0].length, (i, j, a) -> {
        if ((cells[i][j] & 1) == 0) {
            a.setAns(i + "_" + j);
        }
    });
    System.out.println(ans);
}

Das sieht besser aus als das vorherige

Führen Sie es tatsächlich aus, um zu sehen, ob die Ausgabe unseren Erwartungen entspricht;

Das obige ist der detaillierte Inhalt vonWie verwende ich Funktionen zum Durchlaufen eines zweidimensionalen Arrays in Java?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:yisu.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen