본문 바로가기
IT/JAVA

JAVA - 스트림(Stream)

by 삐약 개발자 2024. 12. 2.
반응형

컬렉션을 순회하면서 어떠한 일을 할때 사용함

다양한 데이터 소스로 부터 스트림을 만들수있고 표준화된 방법으로도 다룰수 있음

- 배열이든 컬렉션이든 스트림으로 변경가능

 

스트림은 데이터 소스를 다루는 풍부한 메서드를 제공함

 

스트림은 자바8 부터 도입된 문법임!

 

스트림이란??

배열 및 컬렉션의 저장 요소를 하나씩 참조해서 람다식으로 처리할 수 있도록 하는 반복자

 

스트림을 사용한 반복 처리

import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;

public class PrintNumberOperatorByStream {
    public static void main(String[] args) {
        List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
        Stream<Integer> stream = list.stream();
        stream.forEach(System.out::print);
    }
}

//출력값
12345

 

import java.util.List;

public class DeclarativePrograming {
    public static void main(String[] args){
        // List에 있는 숫자들 중에서 4보다 큰 짝수의 합계 구하기
        List<Integer> numbers = List.of(1, 3, 6, 7, 8, 11);

        int sum =
                numbers.stream()
                        .filter(number -> number > 4 && (number % 2 == 0))
                        .mapToInt(number -> number)
                        .sum(); // 최종연산자는 한번밖에 못씀

        System.out.println("선언형 프로그래밍을 사용한 합계 : " + sum);
    }
}

//출력값
선언형 프로그래밍을 사용한 합계 : 14

 

 

스트림의 특징

  1. 스트림 처리 과정은 생성, 중간 연산, 최종 연산 세 단계의 파이프라인으로 구성될 수 있다.
  2. 스트림은 원본 데이터 소스를 변경하지 않는다(read-only).
  3. 스트림은 일회용이다(onetime-only).
  4. 스트림은 내부 반복자이다.
int[] arr = new int[]{1,2,3,4,5};
IntStream stream = Arrays.stream(arr);
System.out.println(stream.sum());

System.out.println("-".repeat(30));
System.out.println(stream.sum());

 stream 사용후 다시 하려고 하면 오류 == 파이프라인이 닫히면 다시 사용 불가능함

 

배열 스트림 생성

 

Arrays.stream()

   public class StreamCreator {

       public static void main(String[] args) {
           // 문자열 배열 선언 및 할당
           String[] arr = new String[]{"김코딩", "이자바", "박해커"};

           // 문자열 스트림 생성
           Stream<String> stream = Arrays.stream(arr);

           // 출력
           stream.forEach(System.out::println);

       }
   }

   // 출력값
   김코딩
   이자바
   박해커

 

Stream.of()

import java.util.stream.Stream;

public class StreamCreator {

    public static void main(String[] args) {
        // 문자열 배열 선언 및 할당
        String[] arr = new String[]{"김코딩", "이자바", "박해커"};

        // 문자열 스트림 생성
        Stream<String> stream = Stream.of(arr);

        // 출력
        stream.forEach(System.out::println);

    }
}

// 출력값
김코딩
이자바
박해커

 

 

스트림 중간 연산

 

필터링( filter() , distinct() )

 

 filter() -> 조건에 맞는 데이터만을 정제하여 더 작은 컬렉션을 만들어 냄

.distinct() // 중복제거 하기 위하여 사용

 

import java.util.Arrays;
import java.util.List;

public class FilteringExample {
    public static void main(String[] args) throws Exception {

        List<String> names = Arrays.asList("김코딩", "이자바", "박해커", "김코딩", "박해커");

        names.stream()
                .distinct() //중복 제거
                .forEach(element -> System.out.println(element));
        System.out.println();

        names.stream()
                .filter(element -> element.charAt(0) == '김') // 김씨 성을 가진 요소만 필터링
                .forEach(element -> System.out.println(element));
        System.out.println();

        names.stream()
                .distinct() //중복제거
                .filter(element -> element.startsWith("김")) // 김씨 성을 가진 요소만 필터링
                .forEach(element -> System.out.println(element));
    }
}

// 출력값
김코딩
이자바
박해커

김코딩
김코딩

김코딩

 

매핑 ( map() )

map() - 워하는 필드만 추출하거나 특정 형태로 반환하는 중간 연산자

import java.util.Arrays;
import java.util.List;

public class IntermediateOperationExample {
    public static void main(String[] args)
    {
        List<Integer> list = Arrays.asList(1, 3, 6, 9);

        // 각 요소에 3을 곱한 값을 반환
        list.stream().map(number -> number * 3).forEach(System.out::println);
    }

}

// 출력값
3
9
18
27

 

flatMap() - 중복배열을 펼침

// flatMap()
Arrays.stream(namesArray).flatMap(Arrays::stream).forEach(System.out::println);

// 출력값
박해커
이자바
김코딩
나박사

 

 

정렬 ( sorted() )

- 기본적으로 오름차순 ! == sort((a,b) -> a- b)

- 내림차순은 == sort((a,b) -> b - a)

import java.util.Arrays;
import java.util.List;

public class IntermediateOperationExample {
    public static void main(String[] args) {
				// 동물들의 이름을 모아둔 리스트
        List<String> animals = Arrays.asList("Tiger", "Lion", "Monkey", "Duck", "Horse", "Cow");

				// 인자값 없는 sort() 호출
        animals.stream().sorted().forEach(System.out::println);
    }
}

// 출력값
Cow
Duck
Horse
Lion
Monkey
Tiger

 

skip() - 스트림의 일부 요소를 건너뜀

IntStream intStream = IntStream.rangeClosed(1,10);
intStream.skip(5).forEach(System.out::prinln);
//출력
6,7,8,9,10

 

limit() - 스트림의 일부를 자

 // 1~10 범위의 정수로 구성된 스트림 생성
IntStream intStream = IntStream.rangeClosed(1, 10);

// 앞에서부터 5개의 숫자만 출력
intStream.limit(5).forEach(System.out::println);

 // 출력값
    1
    2
    3
    4
    5

 

peek() - 요소들을 순회하며 특정 작업을 수행

( forEach 와 핵심적인 차이는 중간연산자 이냐 최종 연산자 이냐의 차이 )

import java.util.stream.IntStream;

public class IntermediateOperationExample {
    public static void main(String[] args) {

        // 요소들을 사용하여 IntStream 생성
        IntStream intStream3 = IntStream.of(1, 2, 2, 3, 3, 4, 5, 5, 7, 7, 7, 8);

        // 짝수만 필터링하여 합계 구하기
        int sum = intStream3.filter(element -> element % 2 == 0)
                .peek(System.out::println)
                .sum();

        System.out.println("합계 = " + sum);
    }
}

// 출력값
2
2
4
8
합계 = 16

 

 

스트림의 최종연산자

기본 - sum, count, average, max, min

 

매칭 - allMatch, noneMatch, anyMatch

 

 요소소모 - reduce == 각 요소를 연산하여 나온 누적된 결과값을 생성하는데 사용하는 조건식

 

요소수집 - collect == 스트림의 요소들을 List, Set, Map 등 다른 타입의 결과로 수집하고 싶을때

list<Interger> result = currentList.stream()
	.filter()
    .collect(Collectors.toList()); // 최종연산자로 result 에 list 로 저장

 

그 외에도 findAny(), findFirst(), toArray()...등등이 있음

 

Optional Class

 

 

 

반응형

'IT > JAVA' 카테고리의 다른 글

JAVA - 스레드(Thread)  (0) 2024.12.03
JAVA - 파일 입출력(I/O)  (0) 2024.12.03
JAVA - 람다(Lambda)  (0) 2024.12.02
JAVA - 애너테이션(Annotation)  (1) 2024.12.02
JAVA - 컬렉션 프레임 워크  (0) 2024.12.02