Die Grube, die von der Methode Lists.transform verwendet wird - eine Zusammenfassung der Gruben 16 (aktualisiert einmal pro Woche)

Schaffen Sie weiter, beschleunigen Sie das Wachstum! Dies ist der sechste Tag meiner Teilnahme an der „Nuggets Daily New Plan · June Update Challenge“, klicken Sie hier, um die Details der Veranstaltung anzuzeigen

Hintergrund

Die von Google bereitgestellte Lists.transform-Methode kann verwendet werden, um eine Liste einer Entitätsklasse durch eine bestimmte Logik in eine Liste einer anderen Entitätsklasse zu transformieren. Das folgende Beispiel konvertiert beispielsweise eine Liste von Zeichenfolgen in eine Liste von Ganzzahlen.

Beispiel: List<String>A wird in List<Integer>B konvertiert. Wie gezeigt

public static void main(String[] args) {
    List<String> tests = Stream.of("haha", "hehe").collect(Collectors.toList());
    List<Integer> integers = Lists.transform(tests, t -> {
        return t;
    });
}
复制代码

Frage

Die Sammlungs-IDs fügt einen Wert in der Lists.transform-Methode hinzu, wird aber am Ende nicht hinzugefügt.

public static void main(String[] args) {
    List<Long> ids=new ArrayList<>();
    List<Integer> tests = Stream.of("123", "321").collect(Collectors.toList());
    List<Integer> integers = Lists.transform(tests, t -> {
        ids.add(1L);
        return Integer.parseInt(t);
     });
    System.out.println("结果:"+JSON.toJSON(ids));
}
复制代码

Das Druckergebnis sieht wie folgt aus:

Bild.png

Lassen Sie uns einen Haltepunkt treffen, um zu sehen, ob es ausgeführt wird

Sie können sehen, dass der erste Haltepunkt nicht hineingegangen ist und der zweite Haltepunkt direkt gegangen ist.Bild.png

Grund

Aus dem obigen Phänomen ist dies ersichtlich

  • Die Lists.transform-Methode führt die Transformation nicht sofort durch, sondern verzögert die Transformation.
  • Das Abfragen des Quellcodes zeigt, dass unserer sourceList nicht sofort nach dem Ausführen von Lists.transform ein Wert zugewiesen wird, sondern nur in den Typ TransformingRandomAccessList konvertiert wird, wodurch der Iterator neu geschrieben wird. Jedes Mal, wenn wir userFormList iterieren, wird es sein Die Funktion wird zur Zuweisung aufgerufen.
  • Und jedes Mal, wenn die in foreach übergebene Funktion einmal ausgeführt wird, muss die Methode in der Funktion effizienter sein. Daher treten bei unsachgemäßer Verwendung Probleme auf. Das Prinzip ist ein bisschen wie sublist, es gibt tatsächlich eine innere Klasse zurück.

Bild.png

Bild.png

Lösung

Der erste Weg: Verwenden Sie eine Wrapper-Klasse, um das zurückgegebene innere Objekt zu umhüllen

  public static void main(String[] args) {
        List<Long> ids = new ArrayList<>();
        List<String> tests = Stream.of("123", "321").collect(Collectors.toList());
//        List<Integer> integers = Lists.transform(tests, t -> {
//            ids.add(1L);
//            return Integer.parseInt(t);
//        });
        List<Integer> integers = new ArrayList<>(Lists.transform(tests, t -> {
            ids.add(1L);
            return Integer.parseInt(t);
        }));

        System.out.println("结果:" + JSON.toJSON(ids));
    }
复制代码

Ergebnisse der:

Bild.png

Der zweite Weg: Implementieren Sie eine einfache Transformation ohne die von Google bereitgestellte Methode

public static <F, T> List<T> transformList(List<F> fromList, Function<F, T> fuction) {
    if (fromList == null) {
        return new ArrayList<>();
    }
    List<T> lists = new ArrayList<>();
    for (F from : fromList) {
        lists.add(fuction.apply(from));
    }
    return lists;
}
复制代码

Schreiben Sie eine Hauptmethode zum Testen der Verwendung:

  public static void main(String[] args) {
        List<Long> ids = new ArrayList<>();
        List<String> tests = Stream.of("123", "321").collect(Collectors.toList());
//        List<Integer> integers = Lists.transform(tests, t -> {
//            ids.add(1L);
//            return Integer.parseInt(t);
//        });
//        List<Integer> integers = new ArrayList<>(Lists.transform(tests, t -> {
//            ids.add(1L);
//            return Integer.parseInt(t);
//        }));
        List<Tet2> tet2List=new ArrayList<>();
        Tet2 tet2=new Tet2(1L,"haha");
        tet2List.add(tet2);
        List<Tet1> tet1List = transformList(tet2List, m -> {
            Tet1 tet1 = new Tet1();
            tet1.setId(m.getId());
            tet1.setName(m.getName());
            return tet1;
        });
        System.out.println("结果:" + JSON.toJSON(tet1List));
    }
复制代码

Das Druckergebnis sieht wie folgt aus:

Bild.png

Zusammenfassen

Wenn Sie ein Open-Source-Framework eines Drittanbieters verwenden, stellen Sie sicher, dass Sie dessen Prinzipien verstehen, um versteckte Gruben bei der Verwendung von Frameworks von Drittanbietern zu vermeiden.

Ich denke du magst

Origin juejin.im/post/7105581965503365127
Empfohlen
Rangfolge