Java | Varios consejos para hacer el código más elegante a través de Stream

Prefacio

Aunque streamse ha introducido en Java8, pero la mayoría de la gente no tiene que utilizar esta característica tan útil, este documento, al presentar algunas a través del uso, streamhace que el código sea más conciso, legible, para informarle cuando le resulte streamconveniente. Este artículo necesita una comprensión básica de los conceptos básicos y métodos de creación de lambdagramática y suma stream. Para streamlos conceptos básicos y métodos de creación, puedes leer este artículo mío .

habilidad

  • Matriz a colección

    Creo que LeetCodelos socios pequeños que a menudo se cepillan , ocasionalmente encuentran Listsituaciones en las que necesitan convertir con la matriz de tipos básica, y luego necesitan escribir código como el siguiente:

    // 将 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);
    }
    

    Aunque las dos conversiones anteriores no son demasiado problemáticas, pero cada vez que necesite escribir un bucle, especialmente Listcuando necesite usar una matriz temporal cuando la matriz se convierte , hará que la gente se vea muy incómoda, pero si se usa, streamserá grande No es lo mismo, streamel código para lograr la misma función es el siguiente:

    // 将 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());
    

    Se puede encontrar que a través del uso stream, podemos escribir código de manera más coherente, el código es más confiable y fácil de mantener, y el enfoque también puede estar en las funciones comerciales. Creo que incluso si no lambdaestá muy familiarizado con la sintaxis, al leer el código anterior, Es fácil de entender.

  • Cuente el número de elementos en la matriz

    Suponga que ahora necesitamos contar y generar el número de cada elemento y el elemento correspondiente en una matriz con elementos repetidos. Creo que puede pensar en ello. Podemos Mapresolver este problema fácilmente usando uno . El código es el siguiente:

    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));
    

    Si Mapestá APImás familiarizado con el socio, puede escribir el siguiente código más conciso:

    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));
    

    Sin embargo, si streamlo usamos , también podemos escribir código más conciso, sin necesidad de escribir bucles molestos, y solo se necesitan dos líneas de código (para mejorar la legibilidad se agregan saltos de línea):

    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));
    

    Nota

    En el código anterior, Collectors.toMap(k -> k, k -> 1, Integer::sum)esta parte puede no ser fácil de entender. Para los tres parámetros en el interior, el primer parámetro representa arrcada elemento Mapen el medio, keyy el segundo parámetro representa cada uno keycorrespondiente a valuecada uno. Un elemento corresponde al número 1, y el tercer parámetro representa keycómo fusionar si hay los mismos . Aquí, al usar Integer::sum, significa que keycuando se fusionan los mismos elementos, se valueagregan, de modo que cada elemento se realiza Estadísticas del número.

  • Clasificación personalizada de matrices de tipos de datos básicos

    A veces, nos encontraremos con una clasificación personalizada de matrices de tipos de datos básicos. A diferencia de las matrices y colecciones del tipo de empaquetado, el comparador se puede usar directamente. Solo podemos convertir la matriz del tipo de matriz básica al tipo de empaquetado o almacenar en la colección. En, una vez completada la clasificación, se convierte en un tipo básico de matriz. Además, solo podemos lograr esto escribiendo a mano el algoritmo de clasificación y modificando la comparación en el algoritmo de clasificación. Independientemente del método, no podemos enfocarnos en la función lógica, debemos escribir algún código adicional, o incluso modificar la lógica subyacente, al igual que el siguiente código (para lograr el orden inverso de la matriz):

    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;
            }
        }
    }
    

    Podemos encontrar los varios métodos anteriores, todos necesitamos escribir mucho código, no podemos centrarnos en el diseño de clasificación personalizada, pero al usar stream, podemos escribir el siguiente código conciso (si lo desea, también puede Escriba una serie de operaciones en cadena en una línea, pero para facilitar la lectura del código, no se recomienda hacerlo):

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

    Nota

    De hecho, para lograr el orden inverso de la matriz, solo necesitamos llamar Arraysal sortmétodo y luego invertir los elementos de la matriz, pero como es para explicar la ordenación personalizada, en la mayoría de los casos no será tan simple como el orden inverso de la matriz, así que Escribió un código más general.

  • Cuente los k principales elementos de alta frecuencia en la matriz

    Al final, usamos una pregunta para llevar a cabo un combate real con el fin de experimentar mejor streamel poder. Por supuesto, cuando practicamos la pregunta, debemos considerar la solución de la pregunta desde el punto de vista del algoritmo, pero en este artículo, estamos principalmente para explicar streamAsí que no pensamos en el algoritmo, haga clic aquí para ver el enlace original, y si streamlo usamos , podemos escribir el siguiente código simple y fácil de entender:

    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();
        }
    }
    

para resumir

Este artículo presenta algunos streamconsejos sencillos y prácticos . Por supuesto stream, la aplicación es mucho más que eso. Espero que este artículo pueda despertar su streaminterés en aprender . Si hay algún error en este artículo, puede corregirme.

Supongo que te gusta

Origin blog.csdn.net/qq_41698074/article/details/108502976
Recomendado
Clasificación