개발천재

[JAVA] stream 이해하기 본문

개발 준비/JAVA

[JAVA] stream 이해하기

세리블리 2025. 2. 24. 23:21
728x90
반응형

Stream() 이해하기

자바의 Stream은 데이터 컬렉션(예: List, Set, Map 등)을 효율적으로 처리할 수 있도록 도와주는 기능이다.
보통 컬렉션을 반복하면서(for 문, foreach) 데이터를 처리하지만, Stream을 사용하면  for 루프를 사용하지 않아도 더 짧고 가독성 좋은 코드로 데이터를 다룰 수 있다.

 

  • 데이터를 하나씩 처리하는 것이 아니라, 흐름(파이프라인)으로 처리
  • for 문보다 코드가 간결
  • 중간 연산(변환)과 최종 연산(출력, 합산 등)을 분리해서 처리
  • 원본 데이터를 변경하지 않음(불변성 유지)
public class IntArrayTest {
    public static void main(String[] args) {
        int[] arr = {1, 2, 3, 4, 5};
        int sum = Arrays.stream(arr).sum();
        System.out.println(sum);
    }
}

// 출력 15
public class IntArrayTest {
    public static void main(String[] args) {
        int[] arr = {1, 2, 3, 4, 5};
        //배열에 몇개 들어가있는지 확인
        long count = Arrays.stream(arr).count();
        System.out.println(count);
    }
}

 

 

코드의 양이 줄어든다.

public class IntArrayTest {
    public static void main(String[] args) {
        int[] arr = {1, 2, 3, 4, 5};

		// for 루프로 배열 출력
        for(int x : arr) {
            System.out.println(x);
        }
        
        // Stream 이용해서 배열 출력
        Arrays.stream(arr).forEach(x-> System.out.println(x));
    }
}

 

 

또 다른 예제

  • stream() → 리스트에서 Stream 생성
  • filter(조건) → 조건에 맞는 데이터만 남김
  • map(변환) → 데이터를 다른 형태로 변환
  • collect(모으기) → 최종 결과를 리스트로 변환
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class StreamExample {
    public static void main(String[] args) {
        List<String> names = Arrays.asList("apple", "banana", "cherry", "avocado");

        // 'a'로 시작하는 단어만 대문자로 변환하여 리스트로 저장
        List<String> filteredNames = names.stream() // Stream 생성
                .filter(name -> name.startsWith("a")) // 'a'로 시작하는 단어만 필터링
                .map(String::toUpperCase) // 대문자로 변환
                .collect(Collectors.toList()); // 결과를 리스트로 변환

        System.out.println(filteredNames); // 출력: [APPLE, AVOCADO]
    }
}

 

 

Stream 연산 종류

중간 연산 (Intermediate Operations)

중간 연산은 연속해서 연결할 수 있다.

  • filter(Predicate) → 조건에 맞는 요소만 남김
  • map(Function) → 값을 변환 (예: 소문자 → 대문자)
  • sorted() → 정렬
  • distinct() → 중복 제거
  • limit(n) → 앞에서 n개만 선택
  • skip(n) → 앞에서 n개 건너뛰기

 

최종 연산 (Terminal Operations)

최종 연산을 만나면 스트림이 종료되고 결과를 반환하고 최종 연산 후 스트림은 더 이상 다른 연산을 적용할 수 없다.

  • collect(Collectors.toList()) → 리스트로 변환
  • count() → 요소 개수 반환
  • forEach() → 모든 요소 출력
  • reduce() → 누적 연산 (예: 합계 구하기)
  • anyMatch(조건) / allMatch(조건) → 조건 만족 여부 확인
  • sum() → 모든 숫자의 합 구하기

 

stream() sortef() forEach()

import java.util.ArrayList;
import java.util.List;

public class ArrayStreamTest {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("Tomas");
        list.add("Adward");
        list.add("Jack");
        list.stream().forEach(x -> System.out.println( x +"\t"));

        System.out.println("");

        // 리스트 내용 정렬해서 출력하기
        list.stream().sorted().forEach(name -> System.out.println(name));
}

 

 

stream() map() 사용 예제

map은 가공해주는 것, 값을 변환해 주는 것이라고 할 수 있다.

import java.util.ArrayList;
import java.util.List;

public class ArrayStreamTest {
    public static void main(String[] args) {
        // 리스트 생성 및 값 추가
        List<String> list = new ArrayList<>();
        list.add("Tomas");
        list.add("Adward");
        list.add("Jack");

        // 리스트 요소 출력
        list.stream()
            .forEach(x -> System.out.println(x + "\t"));

        System.out.println(); // 줄바꿈

        // 각 요소의 길이 출력
        list.stream()
            .map(String::length) // 문자열 길이 변환
            .forEach(System.out::println);
    }
}

 

 

stream() filter() sorted() forEach() 사용 예제

package streamTest;

import java.util.ArrayList;
import java.util.List;

public class ArrayStreamTest {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("Tomas");
        list.add("Adward");
        list.add("Jack");
        list.stream().forEach(x -> System.out.println( x +"\t"));

        System.out.println("");
        
        // 문자열의 길이가 5이상인 자료만 출력
        // 필터는 조건에 맞는 걸 찾음
        // 출력할 원본이 변하지 않음
        list.stream()
                .filter(x->x.length() >= 5)
                .sorted()
                .forEach(x-> System.out.println(x));
    }
}

 

 

reduce() 사용 예제

public class ReduceTest {
    public static void main(String[] args) {
        String[] greetings = {"안녕하세요~", "hello", "Good Morning", "반갑습니다^^"};

        String result;

        // 람다식으로 reduce() 구현하기
        // sum = sum + i
        // accumulator 가 sum 과 같은 것 -- ""
        result = Arrays.stream(greetings)
                .reduce("",(str1, str2)->{
                   if(str1.length() >= str2.length()) {
                       return str1;
                   } else {
                      return str2;
                   }
                });
        System.out.println(result);

        // BinaryOperator를 이용해서 reduce() 구현하기
        result = Arrays.stream(greetings)
                .reduce(new CompareString()).get();
        System.out.println("====" + result);
    }
}

class CompareString implements BinaryOperator<String> {
    @Override
    public String apply(String str1, String str2) {
        if(str1.length() >= str2.length()) {
            return str1;
        } else {
            return str2;
        }
    }
}
반응형