[JAVA] Stream 주요 문법

JAVA Stream 기초 & 활용

1. Stream 개념

  • 컬렉션, 배열 같은 데이터를 함수형 스타일로 처리할 수 있게 해주는 데이터 흐름 추상
  • 반복문 대신 간결하게 데이터 필터링, 변환, 집계 가능
  • 중간 연산(Intermediate) + 최종 연산(Terminal) 구조
  • 한 번만 사용 가능
  • 병렬 스트림 제외 스트림 연산은 대부분 O(n) 시간복잡도

2. 생성

// 1) 컬렉션에서 스트림 생성
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
System.out.println(list);

Stream<Integer> stream1 = list.stream();
System.out.println(stream1.collect(Collectors.toList()));

// 2) 배열에서 스트림 생성
//primitive 타입은 IntStream, DoubleStream, LongStream 사용 (float형 X)
int[] arr = {1, 2, 3};
IntStream stream2 = Arrays.stream(arr);
//toArray를 통해 자동 int[]로 반환
System.out.println(stream2.toArray()[1]);

// 3) 직접 요소 지정해서 생성
Stream<String> stream3 = Stream.of("a", "b", "c");
System.out.println(stream3.collect(Collectors.toList()));
[1, 2, 3, 4, 5]
[1, 2, 3, 4, 5]
2
[a, b, c]

3. 중간 연산 (Intermediate Operations)

  • 연속 호출 가능
  • 스트림 가공 (필터링, 변환, 정렬)
  • 최종 연산 전까지 실행 안됨(lazy evaluation)

연산 함수

함수명 설명 예시
filter 조건에 맞는 요소만 걸러냄 stream.filter(x -> x > 3)
map 요소를 다른 값으로 변환 stream.map(x -> x * 2)
distinct 중복 제거 stream.distinct()
sorted 정렬 (기본 오름차순), O(NlogN) stream.sorted()
limit 개수 제한 stream.limit(3)
skip 앞의 n개 건너뛰기 stream.skip(2)
peek 중간에 확인하기 stream.peek(x -> System.out.println("peek:" + x))
mapToInt 기본 스트림을 프리미티브 스트림으로 변환 stream.mapToInt(Integer::intValue)
boxed 프리미티브 스트림을 기본 스트림으로 변환 stream.boxed()
코드
// 정수, 문자열 리스트 생성
List<Integer> nlst = new ArrayList<>(Arrays.asList(1,2,3,4,5,6,4,3,2,2,1,6,2,1,12));
List<String> slst = new ArrayList<>(Arrays.asList("곤", "키르아", "히소카", "레오리오", "진", "환영여단", "크라피카"));
  1. filter
    List<Integer> lst1 = nlst.stream()
                         .filter(n -> n > 5)
                         .collect(Collectors.toList());
    System.out.println(lst1);
    
    [6, 6, 12]
    
  2. map
     // 2.1) 값에 연산 적용
     List<Integer> lst2 = nlst.stream()
                             .map(n -> (int)Math.pow(n, 2))
                             .collect(Collectors.toList());
     System.out.println(lst2);
                          
     // 2.2) 문자열 리스트의 요소를 변형하여 정수 리스트로 반환
     List<Integer> lst3 = slst.stream()
                               .map(s -> s.length())
                               //.map(String::length)와 같음
                               .collect(Collectors.toList());
     System.out.println(lst3);
    
    [1, 4, 9, 16, 25, 36, 16, 9, 4, 4, 1, 36, 4, 1, 144]
    [1, 3, 3, 4, 1, 4, 4]
    
  3. distinct
    List<Integer> lst4 = nlst.stream()
                         .distinct()
                         .collect(Collectors.toList());
    System.out.println(lst4);
    
    [1, 2, 3, 4, 5, 6, 12]
    
  4. sorted
     // 4.1) 정수 오름차순
     List<Integer> lst5 = nlst.stream()
                             .sorted()
                             .collect(Collectors.toList());
     System.out.println(lst5);
                            
     // 4.2) 정수 내림차순
     List<Integer> lst6 = nlst.stream()
                             .sorted(Comparator.reverseOrder())
                             .collect(Collectors.toList());
     System.out.println(lst6);
                          
     // 4.3) 문자열 오름차순
     List<String> lst7 = slst.stream()
                             .sorted()
                             .collect(Collectors.toList());
     System.out.println(lst7);
                                          
     // 4.4) 문자열 내림차순
     List<String> lst8 = slst.stream()
                             .sorted(Comparator.reverseOrder())
                             .collect(Collectors.toList());
     System.out.println(lst8);
    
    [1, 1, 1, 2, 2, 2, 2, 3, 3, 4, 4, 5, 6, 6, 12]
    [12, 6, 6, 5, 4, 4, 3, 3, 2, 2, 2, 2, 1, 1, 1]
    [곤, 레오리오, 진, 크라피카, 키르아, 환영여단, 히소카]
    [히소카, 환영여단, 키르아, 크라피카, 진, 레오리오, 곤]
    
  5. limit
    List<String> lst9 = slst.stream()
                         .limit(3)
                         .collect(Collectors.toList());
    System.out.println(lst9);
    
    [곤, 키르아, 히소카]
    
  6. skip
      List<String> lst10 = slst.stream()
                           .skip(2)
                           .collect(Collectors.toList());
      System.out.println(lst10);
    
    [히소카, 레오리오, 진, 환영여단, 크라피카]
    
  7. peek
    slst.stream().peek(s -> System.out.println("캐릭터: "+s))
             .collect(Collectors.toList());
    
    캐릭터: 곤
    캐릭터: 키르아
    캐릭터: 히소카
    캐릭터: 레오리오
    캐릭터: 진
    캐릭터: 환영여단
    캐릭터: 크라피카
    
  8. mapToIntmapToDoublemapToLong
     // mapToInt
     int[] marr =nlst.stream().mapToInt(Integer::intValue).toArray();
     System.out.println(Arrays.toString(marr));
    
    [1, 2, 3, 4, 5, 6, 4, 3, 2, 2, 1, 6, 2, 1, 12]
    
  9. boxed
    List<Integer> blist = Arrays.stream(marr)
               .boxed()
               .collect(Collectors.toList());
    System.out.println(blist);
    
    [1, 2, 3, 4, 5, 6, 4, 3, 2, 2, 1, 6, 2, 1, 12]
    

4. 최종 연산 (Terminal Operations)

  • 결과 생성
  • 반드시 하나 호출해야 스트림 처리

연산 함수

함수명 설명 반환형 예시
collect 결과를 리스트, 세트 등으로 모음 컬렉션 stream.collect(Collectors.toList())
forEach 각 요소에 대해 작업 수행 void stream.forEach(System.out::println)
reduce 요소들을 하나로 합침 Optional / 값 stream.reduce((a,b) -> a+b)
count 요소 개수 계산 long stream.count()
anyMatch 조건 만족하는 요소 존재 여부 boolean stream.anyMatch(x -> x > 5)
allMatch 모든 요소가 조건 만족 여부 boolean stream.allMatch(x -> x > 0)
noneMatch 모든 요소가 조건 불만족 여부 boolean stream.noneMatch(x -> x > 0)
findFirst 첫 번째 요소 반환 Optional stream.findFirst()
toArray 프리미티브 스트림에서 배열로 반환 Array stream.toArray()
toArray 일반 스트림에서 배열로 반환 Array stream.toArray(new T[0])
max/min 프리미티브 스트림에서 최대/최소 반환, getAsInt(빈 배열 유의)orElse등과 함께 사용 OptionalInt OptionalLongOptionalDouble stream.max().getAsInt()
max/min 일반 스트림에서 최대/최소 반환, Comparator과 함께 사용 Optional<T> stream.max(Comparator.naturalOrder())
코드
List<Integer> nlst = new ArrayList<>(Arrays.asList(1,2,3,4,5,6,4,3,2,2,1,6,2,1,12));
List<String> slst = new ArrayList<>(Arrays.asList("곤", "키르아", "히소카", "레오리오", "진", "환영여단", "크라피카"));
  1. collect
    System.out.println(slst.stream()
                                       .collect(Collectors.toList()));
    
    [곤, 키르아, 히소카, 레오리오, 진, 환영여단, 크라피카]
    
  2. forEach
    slst.stream()
     .forEach(System.out :: println);;
     //.forEach(s -> System.out.println(s))와 같음
    
    곤
    키르아
    히소카
    레오리오
    진
    환영여단
    크라피카
    
  3. reduce
     // 3.1) 문자열 합치기
     Optional<String> st = slst.stream()
                             .reduce((a,b)->(a+b));
     System.out.println(st.orElse(null));
                
     // 3.2) 정수 합치기
     Optional<Integer> itL = Stream.of(1,3,5,6,7)
                                   .reduce((a,b) -> (2*a-b));
     System.out.println(itL.orElse(0));
    
    곤키르아히소카레오리오진환영여단크라피카
    -47
    
  4. count
    long a = nlst.stream().count();
    System.out.println(a);
    
    15
    
  5. anyMatch
     // 5.1) 정수 비교
     boolean nm = nlst.stream().anyMatch(n -> n>=30);
     System.out.println(nm);
                    
     // 5.2) 문자열 비교
     boolean sm = slst.stream().anyMatch(s -> s.equals("곤"));
     System.out.println(sm);
    
    false
    true
    
  6. allMatch
    boolean nam = nlst.stream().allMatch(n -> n > 0);
    System.out.println(nam);
    
    true
    
  7. noneMatch
    boolean nnm = nlst.stream().noneMatch(n -> n > 0);
    System.out.println(nnm);
    
    false
    
  8. findFirst
    Optional<String> sf = slst.stream().findFirst();
    System.out.println(sf.orElse(null));
    

5. 예제

  • 정수 배열을 입력받아 중복값을 제거하고 내림차순 정렬 후 반환 메소드
    private static int[] solution(int[] arr) {
          int[] nrr = Arrays.stream(arr)
                          .boxed()
                          .distinct()
                          .sorted(Comparator.reverseOrder())
                          .mapToInt(Integer::intValue)
                          .toArray();
          return nrr;
      }
    

Categories:

Updated:

Leave a comment