Java | Mehrere Tipps, um Code durch Stream eleganter zu gestalten

Vorwort

Obwohl streames in Java8 eingeführt wurde, müssen die meisten Benutzer diese sehr nützliche Funktion nicht verwenden. In diesem Dokument wird streamder Code durch Einführung einiger Funktionen übersichtlicher und lesbarer, damit Sie es streambequem wissen . Dieser Artikel benötigt ein grundlegendes Verständnis der grundlegenden Konzepte und Erstellungsmethoden von lambdaGrammatik und Summe stream. Für streamdie grundlegenden Konzepte und Erstellungsmethoden können Sie diesen Artikel von mir lesen .

Fertigkeit

  • Array zur Sammlung

    Ich glaube, dass LeetCodedie kleinen Partner, die oft putzen , gelegentlich auf ListSituationen stoßen , in denen sie mit dem Array vom Basistyp konvertieren müssen , und dann Code wie den folgenden schreiben müssen:

    // 将 List 元素存储到数组中
    List<Integer> list = new ArrayList<>(Arrays.asList(1, 2, 3, 4, 5));
    int[] arr = new int[list.size()];
    Integer[] temp = list.toArray(new Integer[0]);
    for (int i = 0; i < temp.length; i++) {
          
          
    	arr[i] = temp[i];
    }
    
    // 将数组元素 存储到 List 中
    int[] arr = {
          
          1, 2, 3, 4, 5};
    List<Integer> list = new ArrayList<>();
    for (int val : arr) {
          
          
    	list.add(val);
    }
    

    Obwohl die beiden oben genannten Konvertierungen nicht zu mühsam zu schreiben sind, müssen Sie jedes Mal eine Schleife schreiben, insbesondere Listwenn Sie beim Konvertieren des Arrays ein temporäres Array verwenden müssen. Dadurch sehen die Benutzer sehr unangenehm aus, aber wenn sie verwendet werden, ist sie streamgroß Nicht der gleiche, streamder Code, um die gleiche Funktion zu erreichen, lautet wie folgt:

    // 将 List 元素存储到数组中
    List<Integer> list = new ArrayList<>(Arrays.asList(1, 2, 3, 4, 5));
    int[] arr = list.stream().mapToInt(Integer::intValue).toArray();
    
    // 将数组元素 存储到 List 中
    int[] arr = {
          
          1, 2, 3, 4, 5};
    List<Integer> list = IntStream.of(arr).boxed().collect(Collectors.toList());
    

    Es kann festgestellt werden, dass streamwir durch die Verwendung Code kohärenter schreiben können, der Code zuverlässiger und einfacher zu warten ist und der Fokus auch auf Geschäftsfunktionen liegen kann. Ich glaube, auch wenn Sie lambdamit der Syntax nicht sehr vertraut sind , wenn Sie den obigen Code lesen, Es ist leicht zu verstehen.

  • Zählen Sie die Anzahl der Elemente im Array

    Angenommen, wir müssen jetzt die Anzahl jedes Elements und des entsprechenden Elements in einem Array mit wiederholten Elementen zählen und ausgeben. Ich glaube, Sie können sich das vorstellen. Wir können Mapdieses Problem leicht lösen, indem wir eines verwenden . Der Code lautet wie folgt:

    String[] arr = {
          
          "a", "c", "a", "b", "d", "c"};
    Map<String, Integer> map = new HashMap<>();
    for (String s : arr) {
          
          
        if (map.containsKey(s)) {
          
          
            map.put(s, map.get(s) + 1);
        } else {
          
          
            map.put(s, 1);
        }
    }
    map.forEach((key, value) -> System.out.println(key + " : " + value));
    

    Wenn Sie mit dem Partner besser vertraut Mapsind API, können Sie den folgenden prägnanteren Code schreiben:

    String[] arr = {
          
          "a", "c", "a", "b", "d", "c"};
    Map<String, Integer> map = new HashMap<>();
    for (String s : arr) {
          
          
        map.put(s, map.getOrDefault(s, 0) + 1);
    }
    map.forEach((key, value) -> System.out.println(key + " : " + value));
    

    Wenn streamwir es jedoch verwenden , können wir auch präziseren Code schreiben, ohne störende Schleifen schreiben zu müssen, und es werden nur zwei Codezeilen benötigt (um die Lesbarkeit zu verbessern, werden Zeilenumbrüche hinzugefügt):

    String[] arr = {
          
          "a", "c", "a", "b", "d", "c"};
    Stream.of(arr)
          .collect(Collectors.toMap(k -> k, k -> 1, Integer::sum))
          .forEach((k, v) -> System.out.println(k + " : " + v));
    

    Hinweis

    Im obigen Code ist Collectors.toMap(k -> k, k -> 1, Integer::sum)dieser Teil möglicherweise nicht leicht zu verstehen. Für die drei darin enthaltenen Parameter repräsentiert der erste Parameter arrjedes Element Mapin der Mitte keyund der zweite Parameter repräsentiert jedes Element , das jedem keyentspricht value. Ein Element entspricht der Nummer 1, und der dritte Parameter gibt an, keywie zusammengeführt werden soll, wenn es dasselbe gibt . Hier bedeutet dies, dass beim Zusammenführen Integer::sumdieselben keyElemente valuehinzugefügt werden, sodass jedes Element realisiert wird Statistik der Nummer.

  • Benutzerdefinierte Sortierung von Arrays grundlegender Datentypen

    Manchmal treten benutzerdefinierte Sortierungen von Arrays mit grundlegenden Datentypen auf. Anders als die Arrays und Sammlungen des Verpackungstyps kann der Komparator direkt verwendet werden. Wir können nur das Array des grundlegenden Array-Typs in den Verpackungstyp konvertieren oder in der Sammlung speichern. Nachdem die Sortierung abgeschlossen ist, wird sie in einen grundlegenden Array-Typ konvertiert. Außerdem können wir den Sortieralgorithmus nur von Hand implementieren und den Vergleich im Sortieralgorithmus ändern. Unabhängig von der Methode können wir uns nicht auf die Logikfunktion konzentrieren, sondern müssen zusätzlichen Code schreiben oder sogar die zugrunde liegende Logik ändern, genau wie den folgenden Code (um die umgekehrte Reihenfolge des Arrays zu erreichen):

    int[] arr = {
          
          1, 5, 9, 7, 2, 3, 7, -1, 0, 3};
    // 将数组转为包装类型再进行自定义排序
    Integer[] temp = new Integer[arr.length];
    for (int i = 0; i < arr.length; i++) {
          
          
        temp[i] = arr[i];
    }
    Arrays.sort(temp, Comparator.reverseOrder());
    for (int i = 0; i < temp.length; i++) {
          
          
        arr[i] = temp[i];
    }
    
    // 将数组转为集合类型再进行自定义排序
    List<Integer> list = new ArrayList<>();
    for (int val : arr) {
          
          
        list.add(val);
    }
    list.sort(Collections.reverseOrder());
    for (int i = 0; i < list.size(); i++) {
          
          
        arr[i] = list.get(i);
    }
    
    // 通过手写排序算法修改比较规则实现
    // 为了让代码更加简洁,使用了最暴力且没有优化的冒泡排序
    int[] arr = {
          
          1, 5, 9, 7, 2, 3, 7, -1, 0, 3};
    for (int i = 0; i < arr.length; i++) {
          
          
        for (int j = 0; j < arr.length - i - 1; j++) {
          
          
            if (arr[j] < arr[j + 1]) {
          
          
                int temp = arr[j];
                arr[j] = arr[j + 1];
                arr[j + 1] = temp;
            }
        }
    }
    

    Wir können die oben genannten verschiedenen Methoden finden, wir müssen alle viel Code schreiben, können uns nicht auf das Design der benutzerdefinierten Sortierung konzentrieren, aber mit streamkönnen wir den folgenden prägnanten Code schreiben (wenn Sie möchten, können Sie auch Schreiben Sie eine Reihe von Kettenoperationen in eine Zeile. Aus Gründen der Lesbarkeit des Codes wird dies jedoch nicht empfohlen.

    int[] arr = {
          
          1, 5, 9, 7, 2, 3, 7, -1, 0, 3};
    arr = IntStream.of(arr)
                   .boxed()
                   .sorted(Comparator.reverseOrder())
                   .mapToInt(Integer::intValue)
                   .toArray();
    

    Hinweis

    Um die umgekehrte Reihenfolge des Arrays zu erreichen, müssen wir nur Arraysdie sortMethode aufrufen und dann die Array-Elemente umkehren. Da dies jedoch die benutzerdefinierte Sortierung erklären soll, ist dies in den meisten Fällen nicht so einfach wie die umgekehrte Reihenfolge des Arrays Schrieb allgemeineren Code.

  • Zählen Sie die obersten k Hochfrequenzelemente im Array

    Am Ende verwenden wir eine Frage, um einen tatsächlichen Kampf durchzuführen, um streamdie Macht besser zu erfahren . Wenn wir die Frage üben, müssen wir natürlich die Lösung der Frage aus der Sicht des Algorithmus betrachten, aber in diesem Artikel sollen wir hauptsächlich erklären streamWir denken also nicht über den Algorithmus nach. Klicken Sie hier, um den ursprünglichen Link anzuzeigen. Wenn streamwir ihn verwenden , können wir den folgenden einfachen und leicht verständlichen Code schreiben:

    class Solution {
          
          
        public int[] topKFrequent(int[] nums, int k) {
          
          
            return Arrays.stream(nums)
                         .boxed()
                         .collect(Collectors.toMap(e -> e, e -> 1, Integer::sum))
                         .entrySet()
                         .stream()
                         .sorted((m1, m2) -> m2.getValue() - m1.getValue())
                         .limit(k)
                         .mapToInt(Map.Entry::getKey)
                         .toArray();
        }
    }
    

um zusammenzufassen

Dieser Artikel enthält einige einfache und praktische streamTipps. Natürlich streamist die Anwendung weit mehr als das. Ich hoffe, dieser Artikel kann Ihr streamInteresse am Lernen wecken . Wenn dieser Artikel Fehler enthält, können Sie mich gerne korrigieren.

Ich denke du magst

Origin blog.csdn.net/qq_41698074/article/details/108502976
Empfohlen
Rangfolge