[JAVA] 자바 Stream API 스트림 api 개념 정리 및 예시코드

     

    Stream API란 Java8에서 추가된 Collection입니다.

     

    이 API를 사용하면 데이터를 함수형 프로그래밍의 스타일로 다루며

     

    함수형 프로그래밍의 장점을 활용해 가독성이 높은 코드를 작성할 수 있습니다. 

     

     

    // 즉,  Stream API를 사용하면 유지보수 또한 훨씬 쉬워지겠죠?

     

     

     

    Stream API의 주요 특징

     

    1. Stream(스트림) :

    스트림은 데이터 요소의 연속적인 흐름으로, 컬렉션, 배열, I/O자원 등을 대상으로 합니다.

    스트림은 요소들의 조합을 다루고 변환하는 함수형 스타일의 인터페이스를 제공합니다.

     

    2. Internal Iteration (내부 반복) :

    기존의 Iterator과는 달리, 스트림 API는 내부반복을 사용합니다.

    즉 개발자가 컨트롤하는 Iterator과는 달리, 스트림이 알아서 내부적으로 요소를 반복하며 연산을 수행한다는 의미입니다.

     

    3. 함수형 프로그래밍 :

    스트림 API는 함수형 인터페이스와 람다식을 활용하여 데이터를 처리합니다.

    이를 통해 간결하고 읽기 쉬운 코드를 작성할 수 있습니다. 

     

    4. 중간연산, 그리고 최종연산 :

    스트림 연산은 최종 연산과 중간 연산으로 나뉩니다.

    중간연산은 여러 스트림을 연결하여 새로운 스트림을 반환(return) 하며,

    최종 연산은 스트림의 요소를 소비해 결과를 도출합니다.

     

    5. 지연연산 :

    스트림 연산은 지원연산을 지원합니다. 중간연산은 실제 수행되지 않고,

    최종연산이 호출 될 때까지 연기되는 형태입니다!

    이를 통해 연산의 최적화 및 효율적인 메모리 사용이 가능합니다. 

     

     

    6. 병렬 처리 지원 :

    병렬 스트림을 사용하여 멀티스레드 환경에서 요소를 병렬로 처리할 수 있습니다.

     

    7. 다양한 연산 제공 :

    'map', 'filter', 'reduce' , 'forEach', 'collect' , 'distinct' , 'sorted', 'limit' , 'skip' 등 다양한 연산을 제공하여,

    데이터를 전환, 필터링, 정렬, 제한하는 등의 작업을 수행할 수 있습니다.

     

     

     

     

    stream 만들고 -> 중간연산 -> 최종연산의 형태를 거칩니다.

     

    몇 가지 유용한 메서드 목록들을 공유해 드릴게요.

     

     

    -⑴스트림 생성 메서드  - 

     

    ㆍ Arrays.stream();   주어진 배열로 스트림을 생성합니다.  ↓

    int[] numbers = {1, 2, 3, 4, 5};
    IntStream stream = Arrays.stream(numbers);

     

     

    ㆍList.stream();    주어진 리스트로 스트림을 생성합니다. ↓

    List<String> names = Arrays.asList("Kim", "Lee","Park");
    Stream<String> stream = names.stream();

     

     

    ㆍStream.of();   주어진 요소들로 스트림을 생성합니다  ↓

    Stream<Integer> stream = Stream.of(1,2,3,4,5);

     

     

    -⑵중간 연산 메서드 -

     

    ㆍFiltering (필터링) 

        filter();  주어진 조건에 맞는 요소들로 스트림을 필터링합니다. ↓

    List<Integer> numbers = Arrays.asList(1,2,3,4,5,6,7,8,9,10);
    
    List<Integer> evenNumbers = numbers.stream()
    								   .filter(n->n%2 ==0 )
                                       .collect(Collectors.toList());
                                       
    System.out.println(evenNumbers); // [2,4,6,8,10]

     

     

    ㆍDistincs (중복제거)

       distinct(); 중복 요소를 제거한 스트림을 반환합니다. ↓

    List<Integer> numbers = Arrays.asList(1, 2, 2, 3, 3, 4, 5, 5);
    
    List<Integer> distinctNumbers = numbers.stream()
                                           .distinct()
                                           .collect(Collectors.toList());
    
    System.out.println(distinctNumbers); // [1, 2, 3, 4, 5]

     

     

    ㆍSkip(건너뛰기)

         skip(n) ;   처음 'n' 개의 요소를 건너뛴 스트림을 반환합니다. ↓

    List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
    
    List<Integer> afterSkipping = numbers.stream()
                                         .skip(3)
                                         .collect(Collectors.toList());
    
    System.out.println(afterSkipping); // [4, 5]

     

     

    ㆍFindFirst (첫 번째 요소 찾기)

        findFirst(); 스트림의 첫 번째 요소를 찾습니다. ↓

    List<Integer> numbers = Arrays.asList(1, 3, 5, 6, 7, 8, 9);
    
    Optional<Integer> firstEven = numbers.stream()
                                         .filter(n -> n % 2 == 0)
                                         .findFirst();
    
    if (firstEven.isPresent()) {
        System.out.println(firstEven.get());   // 6
    } else {
        System.out.println("짝수 없음");
    }

     

     

    ㆍLimit (제한)

        limit( n) ;    스트림의 크기를 최대 'n'으로 제한합니다. ↓

    List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
    
    List<Integer> limitedList = numbers.stream()
                                       .limit(3)
                                       .collect(Collectors.toList());
    
    System.out.println(limitedList); //[1, 2, 3]

     

     

    ㆍ Sorted (정렬)

         sorted(); 요소들을 기본 정렬 순서에 따라 정렬합니다.

          sorted( a); 주어진 비교자에 따라 요소들을 정렬합니다. ↓

    List<Integer> numbers = Arrays.asList(5, 3, 9, 1, 6);
    
    List<Integer> sortedNumbers = numbers.stream()
                                         .sorted()
                                         .collect(Collectors.toList());
    
    System.out.println(sortedNumbers); //[1, 3, 5, 6, 9]

     

     

    ㆍMap (매핑)

        map(Function < a, b> map) ; 각 요소를 주어진 함수에 매핑해 새로운 값을 return 합니다. ↓

    List<String> names = Arrays.asList("Kim", "Kang", "No");
    
    List<Integer> nameLengths = names.stream()
                                     .map(String::length)
                                     .collect(Collectors.toList());
    
    System.out.println(nameLengths); //[3, 4, 2]

     

     

     

    -⑶최종 연산 메서드-

    ㆍ Count (요소 개수 계산)

        count(): 스트림의 요소 개수를 반환합니다 ↓ .

    List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
    
    long count = numbers.stream().count();
    
    System.out.println(count); // 5

     

     

    ㆍ Sum (요소 합계)

        sum(): 숫자 요소의 합계를 반환합니다. ↓

    List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
    
    int sum = numbers.stream().mapToInt(Integer::intValue).sum();
    
    System.out.println(sum); // 15

     

     

    ㆍ Average (평균)

        average(): 숫자 요소의 평균 값을 반환합니다 ↓ .

    List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
    
    double average = numbers.stream().mapToDouble(Integer::doubleValue).average().orElse(0.0);
    
    System.out.println(average); // 3.0

     

     

    ㆍ Max (최댓값)

        max(Comparator<T> comparator): 요소 중 최댓값을 반환합니다. ↓

    List<Integer> numbers = Arrays.asList(3, 7, 2, 8, 5);
    
    Optional<Integer> max = numbers.stream().max(Integer::compareTo);
    
    max.ifPresent(value -> System.out.println("최댓값: " + value)); // 최댓값: 8

     

     

     

    ㆍ Min (최솟값)

          min(Comparator<T> comparator): 요소 중 최솟값을 반환합니다. ↓

     

    List<Integer> numbers = Arrays.asList(3, 7, 2, 8, 5);
    
    Optional<Integer> min = numbers.stream().min(Integer::compareTo);
    
    min.ifPresent(value -> System.out.println("최솟값: " + value)); // 최솟값: 2

     

     

     

    ㆍ ForEach (각 요소에 대한 동작 수행)

         forEach(Consumer<T> action): 각 요소에 대해 주어진 동작을 수행합니다. ↓

    List<String> names = Arrays.asList("A", "B", "C");
    
    names.stream().forEach(System.out::println);
    // A
    // B
    // C

     

     

     

    ㆍ Collect (스트림 요소 수집)

        collect(Collector<? super T, A, R> collector): 스트림의 요소를 수집하여 컬렉션 또는 다른 종류의 결과로 반환합니다. ↓

    List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
    
    List<Integer> collected = numbers.stream().filter(n -> n % 2 == 0).collect(Collectors.toList());
    
    System.out.println(collected); // [2, 4]

    댓글