irine3355 / zongang_kmlee

1 stars 0 forks source link

5번째 스트림 km #2

Open irine3355 opened 1 month ago

irine3355 commented 1 month ago

스트림 stream

스트림

특징

스트림 예1:

    public static void main(String[] args) {
        Integer[] nums1={1,2,3,4,5,6,7,8,9,10};

        int result1 = Arrays.stream(nums1).mapToInt(x -> x*x).filter(x ->x%2 ==1).sum();

        System.out.println(result1);
    }

// 터미널 결과:
// 165

결과해석: 1+33+55+77+99 =165 ( 중요: 최종연산 sum을 먼저, 지연연산순서대로, 중간 연산들의 순서에 따라 최적화된 처리를 자동으로 수행하지는 않습니다. )

toArray 예2:

package exam01_1;
import java.util.Arrays;

public class Ex01 {
    public static void main(String[] args) {
            int[] nums = {22, 11, 10, 2, 6,8, 33};
// 배열 임
            Arrays.stream(nums).filter(x->x%2 ==1).map(x -> x*x).forEach(System.out::println);

//먼저, nums 배열을 스트림으로 변환합니다.
//            그런 다음, 스트림의 각 요소를 필터링하여 홀수만 선택합니다.
//                    선택된 홀수들을 제곱하여 매핑합니다.
//                    각 제곱된 홀수를 출력합니다.
//결과:  121 1089 ( 11과 33의 제곱)
//

            int[] nums2 = Arrays.stream(nums).map(x -> x * x).filter(x -> x%2 == 1).toArray();
            System.out.println(Arrays.toString(nums2));

//먼저, nums 배열을 스트림으로 변환합니다.
//            각 요소를 제곱하여 매핑합니다.
//            매핑된 결과 중에서 홀수만 선택합니다.
//                    선택된 홀수들을 새로운 배열로 변환합니다.
//            이 새로운 배열을 출력합니다.
// 결과:  [121, 1089]
        }
    }

mapToInt()

package exam01_1;
//    여기 예제가 있습니다. 이 예제는 문자열 배열을 가지고 각 문자열의 길이를 int로 매핑하여 출력합니다.
//
//            java
//    코드 복사
import java.util.Arrays;
import java.util.stream.IntStream;

public class Ex02 {

        public static void main(String[] args) {
            String[] strings = {"apple", "banana", "orange"};

            // 문자열 배열을 가지고 IntStream을 생성하고 각 문자열의 길이를 int로 매핑합니다.
            IntStream lengthsStream = Arrays.stream(strings).mapToInt(String::length);

            // 각 문자열의 길이를 출력합니다.
            lengthsStream.forEach(System.out::println);
        }
    }
//결과:
5
6
6

String::length 이 ToIntFunction<? super T>에 해당! . String::length은 String 클래스의 length() 메소드를 참조하는 것입니다. . String::length은 ToIntFunction의 applyAsInt 메소드와 시그니처가 일치하므로, 해당 메소드 참조가 ToIntFunction을 나타냅니다. .

연산을 지연의 장점

연산을 지연하는 것은 스트림 API의 핵심적인 장점 중 하나입니다. 이는 다음과 같은 이점을 제공합니다:

  1. 게으른 계산(Lazy Evaluation): 연산을 지연하면 실제로 필요한 시점에만 연산이 수행됩니다. 이는 메모리와 처리 성능을 절약할 수 있습니다. 예를 들어, 대용량 데이터셋에 대해 여러 연산을 수행할 때, 필요한 결과가 나올 때까지 연산을 미룰 수 있습니다.

스트림은 기본적으로 지연 연산을 사용합니다. 이는 스트림의 특성 중 하나이며, 많은 연산이 게으른 계산 방식으로 작동합니다. 그러나 몇 가지 연산은 즉시 실행되기도 합니다. 예를 들어, collect() 메서드는 최종 연산으로써 스트림의 모든 요소를 수집하여 다른 데이터 구조로 변환하므로 즉시 실행됩니다. 또한 forEach() 메서드는 각 요소에 대해 주어진 동작을 즉시 수행합니다.

  1. 단계적인 처리(Step-by-Step Processing): 연산을 지연하면 각 단계의 결과를 중간 스트림으로 얻을 수 있습니다. 이는 중간 결과를 다른 연산에 활용하거나 중간 결과를 조작하여 최종 결과를 도출할 수 있습니다.

  2. 최적화(Optimization): 지연된 연산은 최적화에 유리합니다. 예를 들어, 필터링 연산을 수행할 때, 필요한 요소만 처리하여 불필요한 계산을 줄일 수 있습니다.

따라서 연산을 지연하면 자원을 효율적으로 활용하고, 복잡한 데이터 처리 과정을 보다 단순하게 표현할 수 있습니다.

빈 스트림

요소가 하나도 없는 비어있는 스트림 스트림에서 연산을 수행한 결과가 하나도 없을 때, null 보다 빈 스트림을 반환하는 것이 좋다. 스트림에서 null 값을 0으로 처리하는 이유는 주로 다음과 같습니다:

  1. 연산의 안정성: null 값이 연산에 포함될 경우 예외가 발생할 수 있습니다. 예를 들어, null 값을 포함한 배열에서 합계를 계산하려고 하면 NullPointerException이 발생할 수 있습니다. null을 0으로 처리하면 이러한 예외를 방지할 수 있습니다.

리듀싱 - reduce() 스트림의 요소를 줄여나가면서 연산을 수행하고 최종결과를 반환한다. 매개변수의 타입은 BinaryOperator이다. 처음 두 요소를 가지고 연산한 결과를 가지고 그 다음 요소를 연산한다.

day19/StreamEx5.java
package day19;

import java.util.*;
import java.util.stream.*;

public class StreamEx5 {
    public static void main(String[] args) {
        String[] strArr = {
            "Inheritance", "Java", "Lambda", "stream",
            "optionalDouble", "IntStream", "count", "sum"
        };
        Stream.of(strArr).forEach(System.out::println);
        // Stream.of(strArr)를 사용하여 문자열 배열을 스트림으로 변환하고, forEach를 사용하여 각 요소를 출력합니다.

        boolean noEmptyStr = Stream.of(strArr).noneMatch(s->s.length() == 0);
        Optional<String> sWord = Stream.of(strArr)
                    .filter(s->s.charAt(0) == 's').findFirst();
        //findFirst를 사용하여 배열에서 's'로 시작하는 첫 번째 단어를 찾습니다.

        System.out.println("noEmptyStr=" + noEmptyStr);
        System.out.println("sWord=" + sWord.get());

        // Stream<String[]>을 IntStream으로 변환
        IntStream intStream1 = Stream.of(strArr).mapToInt(String::length);
        IntStream intStream2 = Stream.of(strArr).mapToInt(String::length);
        IntStream intStream3 = Stream.of(strArr).mapToInt(String::length);
        IntStream intStream4 = Stream.of(strArr).mapToInt(String::length);
        //mapToInt를 사용하여 각 문자열의 길이를 IntStream으로 변환합니다.

        int count = intStream1.reduce(0, (a,b) -> a + 1);
//intStream1은 문자열 배열의 각 문자열의 길이를 담고 있는 IntStream입니다.
reduce 메서드는 스트림의 요소를 줄여 하나의 결과값을 생성합니다.
초기값으로 0을 설정하고, 각 요소를 방문할 때마다 a + 1 연산을 수행합니다.
여기서 a는 누적값이고, b는 현재 요소의 값입니다.
이 코드는 각 요소를 방문할 때마다 누적값에 1을 더하여 요소의 개수를 계산합니다. 결과적으로 count 변수에는 요소의 개수가 저장됩니다.

        int sum = intStream2.reduce(0,  (a,b) -> a + b);
//intStream2는 문자열 배열의 각 문자열의 길이를 담고 있는 IntStream입니다.
초기값으로 0을 설정하고, 각 요소를 방문할 때마다 a + b 연산을 수행합니다.
여기서 a는 누적값이고, b는 현재 요소의 값입니다(즉, 문자열의 길이).
이 코드는 각 요소의 길이를 누적하여 모두 더한 값을 계산합니다. 결과적으로 sum 변수에는 모든 문자열의 길이의 합이 저장됩니다.

        OptionalInt max = intStream3.reduce(Integer::max);
        OptionalInt min = intStream4.reduce(Integer::min);
        //reduce를 사용하여 각 IntStream에 대해 다양한 연산을 수행합니다. 

        System.out.println("count=" + count);
        System.out.println("sum=" + sum);
        System.out.println("max=" + max.getAsInt());
        System.out.println("min=" + min.getAsInt());
    }
}
결과:
Inheritance
Java
Lambda
stream
optionalDouble
IntStream
count
sum
noEmptyStr=true
sWord=stream
count=8
sum=58
max=14
min=3
irine3355 commented 1 month ago

mapToInt()

스크린샷 2024-05-01 225029