Java | Stream을 통해 코드를 더 우아하게 만드는 몇 가지 팁

머리말

비록 streamJava8에서 소개되었지만 대부분의 사람들은이 매우 유용한 기능을 사용할 필요가 없지만,이 문서에서는 사용 stream통해 몇 가지를 소개 하여 코드를 더 간결하고 읽기 쉽게 만들어 편의에 알립니다 stream. 이 기사는 lambda문법과 요약 의 기본 개념과 생성 방법 stream대한 기본적인 이해가 필요 하며 stream, 기본 개념과 생성 방법 대해서는 기사를 읽을 수 있습니다 .

기술

  • 컬렉션에 배열

    나는 자주 브러싱 LeetCode하는 소규모 파트너 List가 기본 유형 배열 로 변환해야하는 상황에 직면 하고 다음과 같은 코드를 작성해야한다고 생각합니다.

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

    위의 두 가지 변환은 그리 번거롭지는 않지만 루프를 작성해야 할 때마다, 특히 배열이 변환 List될 때 임시 배열을 사용해야 할 때마다 사람들이 매우 불편 해 보이지만 사용하면 stream커질 것입니다 동일하지는 않지만 stream동일한 기능을 수행하는 코드는 다음과 같습니다.

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

    사용을 통해 stream보다 일관되게 코드를 작성할 수 있고, 코드가 더 안정적이고 유지 관리가 쉬우 며, 업무 기능에도 초점을 맞출 수 있음을 알 수 있습니다. lambda위의 코드를 읽을 때 구문에 익숙하지 않더라도 , 이해하기 쉽습니다.

  • 배열의 요소 수 계산

    이제 반복되는 요소가있는 배열의 각 요소와 해당 요소의 수를 세고 출력해야한다고 가정 해 보겠습니다. 생각할 수 있다고 생각합니다. 하나 Map사용 하면이 문제를 쉽게 해결할 있습니다. 코드는 다음과 같습니다.

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

    당신이 경우 Map입니다 API파트너에 익숙해 다음과 같은 더 간결한 코드를 작성할 수 있습니다 :

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

    그러나 그것을 사용하면 stream성가신 루프를 작성할 필요없이 더 간결한 코드를 작성할 수도 있으며, 가독성을 높이기 위해 줄 바꿈이 추가되었습니다.

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

    노트

    위의 코드 Collectors.toMap(k -> k, k -> 1, Integer::sum)에서이 부분은 이해하기 쉽지 않을 수 있는데, 내부에있는 세 개의 매개 변수 중 첫 번째 매개 변수는 중간에있는 arr각 요소 Mapkey나타내고 두 번째 매개 변수는 각각에 key해당하는 각 요소 나타냅니다 value. 요소는 숫자 1에 해당하고 세 번째 매개 변수는 같은 요소가 있을 경우 key병합하는 방법을 나타냅니다 . 여기서를 사용 하면 Integer::sum같은 key요소가 병합 될 때 value추가되어 각 요소가 실현됨을 의미합니다. 숫자의 통계.

  • 기본 데이터 유형 배열의 사용자 정의 정렬

    때때로 우리는 기본 데이터 유형의 배열의 사용자 정의 정렬이 발생합니다. 패키징 유형의 배열 및 컬렉션과 달리 비교기는 직접 사용할 수 있습니다. 기본 배열 유형의 배열을 패키지 유형으로 변환하거나 컬렉션에 저장할 수만 있습니다. 에서는 정렬이 완료된 후 기본형 배열로 변환되며, 정렬 알고리즘을 직접 구현하고 정렬 알고리즘에서 비교를 수정할 수 있습니다. 방법에 관계없이 논리 함수에 초점을 맞출 수 없으며, 추가 코드를 작성하거나, 다음 코드와 같이 기본 논리를 수정해야합니다 (배열 역순을 달성하기 위해).

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

    위의 몇 가지 방법을 찾을 수 있습니다. 우리 모두는 많은 코드를 작성해야하며 맞춤 정렬 설계에 집중할 수 없지만를 사용 stream하여 다음과 같은 간결한 코드를 작성할 수 있습니다 (원하는 경우 일련의 체인 연산을 한 줄에 작성하지만 코드 가독성을 위해 권장하지 않습니다.)

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

    노트

    사실, 배열의 역순을 얻으려면 메서드 를 호출 Arrayssort다음 배열 요소를 반대로하면되지만 사용자 지정 정렬을 설명하기위한 것이므로 대부분의 경우 배열의 역순만큼 간단하지 않습니다. 보다 일반적인 코드를 작성했습니다.

  • 배열에서 상위 k 개의 고주파수 요소 계산

    결국 우리는 더 나은 stream힘을 경험하기 위해 실제 전투를 수행하기 위해 질문을 사용합니다 . 물론 우리가 질문을 연습 할 때 우리는 알고리즘의 관점에서 질문의 해결책을 고려할 필요가 있지만,이 기사에서는 주로 설명합니다 stream따라서 알고리즘에 대해 생각하지 않고 여기를 클릭 하여 원본 링크 확인하고이를 사용 stream하면 다음과 같은 간단하고 이해하기 쉬운 코드를 작성할 수 있습니다.

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

요약하자면

이 기사에서는 간단하고 실용적인 몇 가지 stream팁을 소개합니다 . 물론 stream응용 프로그램은 그 이상입니다.이 기사가 학습에 대한 stream관심을 불러 일으킬 수 있기를 바랍니다.이 기사에 오류가 있으면 저를 수정해도 좋습니다.

추천

출처blog.csdn.net/qq_41698074/article/details/108502976