ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [JAVA8] About Stream 스트림에 대하여
    Backend/JAVA&JAVA8 2022. 5. 5. 13:37

     

     
    안녕하세요.

    오늘은 JAVA로 개발을 하면서 적잖이 충격을 받았던 JAVA8에 대해서 이야기해보고, 또 어떻게 사용하고 있는지 기능 별로 정리하여 제가 추후에 저의 블로그를 보고 참고하여 사용할 수 있게 끔 정리하는 포스팅을 진행하려 합니다.

     

    저는 정확히는 람다라는 개념을 Javascript에서 처음 접하게 되었습니다.

    이때 저는 처음으로 제 머릿속에서, 본격적으로 함수형 프로그래밍에 대한 개념이 제 머릿속에서 생겨났다고 봅니다.

     

    굉장히 낯설었던 기억이 납니다.

     

    JAVA8 이전에는 어떠한 자료구조에 대해서 순환하며 데이터를 뽑으려면 iterator와 함께 while 문을 사용하거나 for 문을 돌려야 했습니다.

    아래처럼요.

     

    // Java7 이전의 코드
    
    List<TestData> testDataList = testData();
    
    Iterator<TestData> testDataIteratorList = testDataList.iterator();
    
    // 외부 반복자
    
    while (testDataIteratorList.hasNext()) {
    
    TestData testData = testDataIteratorList.next();
    
    System.out.println(testData.getType());
    
    }
     

    외부 반복자와 while 문을 통하여 다음 값이 있으면 값을 출력하고, 없으면 출력하지 않는 방식이었습니다.

    '기존 방식이 나쁘다'라는 이야기가 아닙니다.

     

    JAVA8 이후로부터 추구하는 방식은 조금 다릅니다.

    '내부 반복자'라는 개념이 추가되어 Collection 내부에서 요소들을 반복 시키고, 개발자는 요소 당 처리해야 할 코드만 제공하는 개념인 Stream이 추가되었습니다.

    개발자는 요소 처리 코드에만 집중할 수 있고, CPU를 최대한 활용할 수가 있습니다.

    각각의 요소들을 분배시켜 병렬 처리 작업을 할 수 있습니다.

     

    아래 예제를 보시면....

    List<Integer> numList = new ArrayList<>();
    
    numList.add(0, 1);
    
    numList.add(1, 12);
    
    numList.add(2, 33);
    
    numList.add(3, 45);
    
    numList.add(4, 66);
    
    numList.add(5, 7);
    
    for (Integer num: numList) {
    
    System.out.println(num);
    
    }
     

    전통적인 for(int i = 0;i < 0; i++) 이러한 방식도 있겠지만, 위처럼 쓰기도 합니다.

     

    그리고 JAVA8 이후부터는 아래와 같이 합니다.

     

    List<Integer> numList = new ArrayList<>();
    
    numList.add(0, 1);
    
    numList.add(1, 12);
    
    numList.add(2, 33);
    
    numList.add(3, 45);
    
    numList.add(4, 66);
    
    numList.add(5, 7);
    
    Stream<Integer> streamInt = numList.stream();
    
    streamInt.forEach(System.out::println);
    
     

    리스트를 순환하여 무언가 값을 뽑아줄 수 있다면, filtering을 할 수도 있지 않을까요?

    맞습니다.

    아래와 같이 filtering이 가능합니다.

     

    List<Integer> numList = new ArrayList<>();
    
    numList.add(0, 1);
    
    numList.add(1, 12);
    
    numList.add(2, 33);
    
    numList.add(3, 45);
    
    numList.add(4, 66);
    
    numList.add(5, 7);
    
    List<Integer> filteringNumList = numList
                                         .stream()
                                         .filter(num -> num.intValue() > 10)
                                         .collect(Collectors.toList());
    
    filteringNumList.forEach(System.out::println);
     

     

    조건에 부합하는 값을 우선적으로 하나 뽑을 수도 있습니다.

    그리고 조건이 없을 때에는 특정 값을 반환할 수도 있고요.

     

    List<Integer> numList = new ArrayList<>();
    
    numList.add(0, 1);
    
    numList.add(1, 12);
    
    numList.add(2, 33);
    
    numList.add(3, 45);
    
    numList.add(4, 66);
    
    numList.add(5, 7);
    
    Integer number = numList
                         .stream()
                         .filter(resultInt -> resultInt.intValue() > 2)
                         .findFirst()
                         .orElse(0);
    
    System.out.println(number);
     

    제가 위의 간단한 코드를 짜면서 머릿속으로 시뮬레이션 하는 과정은 아래와 같습니다.

     

    1.Stream 화하고자 하는 자료구조 리스트 만들기

    2.Stream 적용

    3.Filtering 혹은 map 적용(원하는 데이터를 솎아내기 위한 작업)

    4.Collect로 흩어진 데이터들 모으기

     

    위와 같습니다.

    오늘은 기본적인 stream, 그리고 JAVA8이 기존 JAVA와는 다르게 어떤 식으로 데이터를 변경하는지에 대한 포스팅을 진행해 보았습니다.

     

    저도 한참 써보고 있는 중이기 때문에, 이 포스팅이 별 도움을 못 드릴 수도 있겠습니다만

    업계에서 주력으로 쓰이고 있는 JAVA의 버전인 만큼 신경 써서 포스팅할 예정입니다.

     

    Lambda에 관련돼서는....

    처음에는 익명으로 무언가를 넘겨주고, 함수의 이름 없이 무언가를 실행시켜준다는 것이 매우 낯설었습니다.

    그런데 기존 방식대로 코딩해보고, 함수형 프로그래밍에서 추구하는 방식 대로도 개발을 해보니.....

    어디까지나 개인적인 생각입니다만 함수형 프로그래밍의 이전 버전에 대해서 제대로 알고 있다면 함수형 프로그래밍이 주는 편리함을 잊기 힘들 듯합니다.

     

    오늘은, 여러 가지 자료구조를 함수형 프로그래밍에서 추구하는 방식으로 개발하기 위해서 간단하게 코드를 작성해 보았습니다.

     

    다음 포스팅에서는 Java8의 핵심기능인 Optional에 대해 비교하는 시간을 가져볼까 합니다.

     

    감사합니다.

     

    댓글

Designed by Tistory.