Java | Several tips to make code more elegant through Stream

Preface

Although streamit has been introduced in Java8, but most people do not have to use this very useful feature, this paper by introducing a few through the use streammake the code more concise, readable, to let you know streamat the convenience of. This article needs a basic understanding of the basic concepts and creation methods of lambdagrammar and sum stream. For streamthe basic concepts and creation methods, you can read this article of mine .

skill

  • Array to collection

    I believe that LeetCodethe small partners who often brush , occasionally encounter Listsituations where they need to convert with the basic type array, and then they need to write code like the following:

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

    Although the above two conversions are not too troublesome, but each time you need to write a loop, especially Listwhen you need to use a temporary array when the array is converted , it will make people look very uncomfortable, but if used, it streamwill be big Not the same, streamthe code to achieve the same function is as follows:

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

    It can be found that through use stream, we can write code more coherently, the code is more reliable and easy to maintain, and the focus can also be on business functions. I believe that even if you lambdaare not very familiar with the syntax, when reading the code above, It is easy to understand.

  • Count the number of elements in the array

    Suppose we now need to count and output the number of each element and corresponding element in an array with repeated elements. I believe you can think of it. We can Mapeasily solve this problem by using one . The code is as follows:

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

    If you Mapare APImore familiar with the partner, you may write the following more concise code:

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

    However, if streamwe use it , we can also write more concise code, without the need to write annoying loops, and only two lines of code are needed (to improve readability, line breaks are added):

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

    note

    In the above code, Collectors.toMap(k -> k, k -> 1, Integer::sum)this part may not be easy to understand. For the three parameters inside, the first parameter represents arreach element Mapin the middle, keyand the second parameter represents each keycorresponding to valueeach. An element corresponds to the number 1, and the third parameter represents keyhow to merge if there are the same . Here, by using Integer::sum, it means that keywhen the same elements are merged, they valueare added, so that each element is realized Statistics of the number.

  • Custom sorting of arrays of basic data types

    Sometimes we will encounter custom sorting of arrays of basic data types. Different from the arrays and collections of the packaging type, the comparator can be used directly. We can only convert the array of the basic array type to the packaging type or store in the collection. In, after the sorting is completed, it is converted to a basic type of array. Furthermore, we can only achieve this by handwriting the sorting algorithm and modifying the comparison in the sorting algorithm. Regardless of the method, we can't focus on the logic function, we must write some additional code, or even modify the underlying logic, just like the following code (to achieve the array reverse order):

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

    We can find the above several methods, we all need to write a lot of code, can not focus on the design of custom sorting, but by using stream, we can write the following concise code (if you want, you can also Write a series of chain operations on one line, but for code readability, it is not recommended to do that):

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

    note

    In fact, in order to achieve the reverse order of the array, we only need to call Arraysthe sortmethod and then reverse the array elements, but because it is to explain custom sorting, in most cases it will not be as simple as the reverse order of the array, so I Wrote more general code.

  • Count the top k high-frequency elements in the array

    In the end, we use a question to conduct actual combat in order to better experience streamthe power. Of course, when we practice the question, we need to consider the solution of the question from the point of view of the algorithm, but in this article, we are mainly to explain streamSo we don’t think about the algorithm, click here to view the original link, and if streamwe use it , we can write the following simple and easy-to-understand code:

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

to sum up

This article introduces a few simple and practical streamtips. Of course stream, the application is far more than that. I hope this article can arouse your streaminterest in learning . If there are any errors in this article, you are welcome to correct me.

Guess you like

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