Coding History

국비 지원 IT(웹앱개발) 취업반 강의 13일차

BlackBirdIT 2024. 6. 24. 18:30

스트림

저번주 금요일에 냈던 문제를 스트림을 활용해서 풀어보라고 하셔서 스트림을 구글링 했는데 무슨소린지 하나도 모르겠다. 일단 스트림을 활용하지 않은 코드는

import java.util.Arrays;
import java.util.Scanner;

class Main2 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);

        String[] inputs = sc.nextLine().split(" ");

        long sum = 0;

        for (String inputData : inputs) {
           sum += Long.parseLong(inputData);
        }

        System.out.println(sum);

        sc.close();
    }
}

스트림을 활용한 코드는

import java.util.Arrays;
import java.util.Scanner;

class Main2 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);

        String[] inputs = sc.nextLine().split(" ");

        long sum = Arrays.stream(inputs)
                .mapToLong(e -> Long.parseLong(e))// -> 은 함수 실행을 의미
                .sum();

//        long sum = 0;
//
//        for (String inputData : inputs) {
//            sum += Long.parseLong(inputData);
//        }
//
        System.out.println(sum);

        sc.close();
    }
}

이러하다. 스트림을 활용하면 가독성과 코드가 줄어들어서 실수도 함께 줄어든다고 한다.

"스트림"의 사전적 의미는 "흐르다"인데, 데이터가 흘러가고 거기에 그물을 쳐서 데이터를 거르는 일을 한다고 한다.
특정 함수에게 일을 통째로 맡긴다는 개념이라고 한다.

class Main2 {
    public static void main(String[] args) {
        //일반
        for (int i = 1; i <= 10; i++) {
            System.out.println(i);
        }

        //스트림 1
        IntStream.range(1, 10)
                .forEach(i ->
                        System.out.println(i)
                );
        //스트림2
        IntStream.range(1,11)
                .forEach(System.out::println);
    }
}

이렇듯 방법 중 하나지 필수로 사용한다거나 그런건 아니라고 한다.

//위의 반복분이랑 같은 값을 출력해보기(스트림 사용해서)

class Main2 {
    public static void main(String[] args) {
        //일반
        int[] arr = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

        for (int i = 0; i < arr.length; i++) {
            arr[i] *= 2;
        }
//        for (int i = 0; i < arr.length; i++) {
//            System.out.println(arr[i]);
//        }
        System.out.println(Arrays.toString(arr));
        //스트림 1
        IntStream.range(1, 11)
                .map(v -> v * 2)
                        .forEach(System.out::println);
    }
}
//내가 푼 답안 출력
//[2, 4, 6, 8, 10, 12, 14, 16, 18, 20]
//2
//4
//6
//8
//10
//12
//14
//16
//18
//20
//1
//2
//3
//4
//5
//6
//7
//8
//9
//10
class Main2 {
    public static void main(String[] args) {
        //일반
        int[] arr = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

        for (int i = 0; i < arr.length; i++) {
            arr[i] *= 2;
        }
//        for (int i = 0; i < arr.length; i++) {
//            System.out.println(arr[i]);
//        }
        System.out.println(Arrays.toString(arr));
        System.out.println("===============");
        //스트림 1
        IntStream.range(1, 11)
                .map(v -> v * 2)
                        .forEach(System.out::println);

        System.out.println("===============");
        //강사님 답안
        arr = new int[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

        int[] rsArray = Arrays.stream(arr)
                .map(e -> {
                    return e * 2;
                }).toArray();
        System.out.println(Arrays.toString(rsArray));

        System.out.println("===============");
        //강사님 답안2
        arr = new int[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

        int[] resultArr = Arrays.stream(arr)
                .map(e -> e * 2) // 이런식으로 줄여쓸 수 있다.
                .toArray();

        System.out.println(Arrays.toString(arr));
        System.out.println(Arrays.toString(resultArr));
    }
}
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

class Main2 {
    public static void main(String[] args) {
        //일반 //홀수를 걸러낼거야.
        int[] arr = {33, 2, 55, 4, 51, 6, 71, 18, 29, 10};

        int rsArrLen = 0;

        for (int n : arr) { //arr 순회할거야 짝수의 개수를 세어서 rsArrLen에 저장할거야.
            if (n % 2 == 0) {
                rsArrLen++;
            }
        }
        int[] rsArr = new int[rsArrLen]; //길이가 rsArrLen인 정수형 배열을 선언. 이 배열은 짝수만 저장하기 위한 배열

        int rsArrLastIndex = -1; //인덱스 추적

        for (int n : arr) { //두 번째 for 루프는 배열 arr의 모든 요소를 다시 순회
            if (n % 2 != 0) { //현재 요소 n이 홀수인지를 확인
                continue; //만약 n이 홀수라면, continue 문을 통해 현재 반복을 건너뜀.
            }
            rsArr[++rsArrLastIndex] = n;
        }
        System.out.println(Arrays.toString(rsArr));
        System.out.println("=================");
        //내 풀이
        List<Integer> arr2 = Arrays.asList(33, 2, 55, 4, 51, 6, 71, 18, 29, 10);
        List<Integer> evenNumbers = arr2.stream()
                .filter(n -> n % 2 == 0)
                .collect(Collectors.toList());
        System.out.println(evenNumbers);

        //강사님 풀이
        System.out.println("=================");

        arr = new int[]{33, 2, 55, 4, 51, 6, 71, 18, 29, 10};

        rsArr = Arrays.stream(arr)
                .filter(e -> e % 2 == 0)
                .map(e -> e * 2) //맵 기능 설명을 위해 곱해봄
                .toArray();
        System.out.println(Arrays.toString(rsArr));
    }
}
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

class Main2 {
    public static void main(String[] args) {
        //일반 //홀수를 걸러낼거야.
        int[] arr = {33, 2, 55, 4, 51, 6, 71, 18, 29, 10};

        List<Integer> resultAl = new ArrayList<>();

        //filter
        for (int n : arr) if (n % 2 == 0) resultAl.add(n); // 중괄호 안이 한줄이면 이렇게 써도돼.

        //map
        for (int i = 0; i < resultAl.size(); i++) {
            int newValue = resultAl.get(i) * 2;
            resultAl.set(i, newValue);
        }
        System.out.println(resultAl);

        System.out.println("=================");

        //스트림
        arr = new int[]{33, 2, 55, 4, 51, 6, 71, 18, 29, 10};

        resultAl = Arrays.stream(arr)
                .filter(e -> e % 2 == 0)
                .map(e -> e * 2)
                .boxed() // new Integer 과 같은 말.
                .collect(Collectors.toList());
        System.out.println(resultAl);
    }
}

이렇게 다양하게 사용해보니까 조금은 이해가 되는 것 같다. 강사님은 그렇게까지 중요한 것은 아니라고 하셨고 이런게 있다는 것 정도만 알고 있으라고 하셨는데 코드도 간결하고 읽기도 쉬워서 좀 더 파볼까 싶다.

다음으로 기초의 반복 학습을 강조하시며 약간 고급으로 넘어갔다.

다항식 계산기 만들기를 이후에 계속 진행했는데 이건 깃허브에 올렸다.. 정리하기 어려울 것 같으니 내일부터는 순차적으로 올려보도록 하겠다.