자바 스트림(Stream)

방지환·2024년 6월 10일

Java

목록 보기
3/19

스트림(Stream)

  • 스트림(Stream) API은 람다식(Lambda Expression)를 이용한 기술 중에 하나로 데이터 소스(컬렉션, 배열, 난수, 파일 등…)를 조작 및 가공, 변환하여 원하는 값으로 반환해주는 인터페이스를 의미합니다.
  • 해당 기능을 사용하기 위해서는 Java 1.8 이상의 버전을 사용해야 합니다.
  • 해당 스트림 인터페이스는 import java.util.stream 에 포함되어 있습니다.

특징

  • 스트림은 외부 반복을 통해 작업하는 컬렉션과는 달리 내부 반복(Internal iteration)을 통해 작업을 수행합니다.
  • 스트림은 재사용이 가능한 컬렉션과는 달리 단 한번만 사용할 수 있습니다.
  • 스트림은 원본 데이터를 변경하지 않습니다.
  • 스트림의 연산은 필터-맵(filter-map) 기반의 API를 사용하여 지연(lazy) 연산을 통해 성능을 최적화합니다.

연산과 메서드

  • 스트림이 제공하는 다양한 연산을 이용해 복잡한 작업들을 간단히 처리 가능
  • 스트림에 제공하는 연산은 중간연산최종 연산으로 분류
    최종 연산 : 연산 결과가 스트림이 아닌 연산. 스트림의 요소를 소모하므로 단 한번만 가능하다.

사용법

  • 배열 스트림 : Arrays.stream()

	Stream<String> strStream = Stream.of("a", "b", "c"); // 가변인자
	Stream<String> strStream = Stream.of(new String[]{"a", "b", "c"});
	Stream<String> strStream = Arrays.stream(new String[]{"a", "b", "c"});
	Stream<String> strStream = Arrays.stream(new String[]{"a", "b", "c"}, 0, 3);
  • 특정 범위의 정수

	IntStream intStream = IntStream.range(1, 5); // 1,2,3,4
	IntStream intStream = IntStream.rangeClosed(1, 5); // 1,2,3,4,5
  • 컬렉션 스트림

	List<String> list = Arrays.asList("a","b","c");
	Stream<String> stream = list.stream();
  • 람다식 Stream.generate(), iterate()

	Stream<String> generatedStream = Stream.generate(()->"a").limit(3);
	// 생성할 때 스트림의 크기가 정해져있지 않기(무한하기)때문에 최대 크기를 제한해줘야 한다.
	Stream<Integer> iteratedStream = Stream.iterate(0, n->n+2).limit(5); 		//0,2,4,6,8

중간 연산

  • 스트림 자르기 - skip()-앞에서부터 n개 skip하기,limit()-최대 크기 제한
  • 스트림 요소 걸러내기 - filter(), distinct()
 	//filter
 	IntStream test1 = IntStream.rangeClosed(1, 10); // 1 ~ 10 숫자
 	test1.filter(i -> i%2==0).forEach(System.out::print);
 	//distinct
 	IntStream test2 = IntStream.of(1, 2, 3, 3, 2, 5, 7, 6, 9);
 	test2.distinct().forEach(System.out::print);
  • 정렬
	Stream<String> strStream = Stream.of("b", "cc", "D", "C", "AA", "F");
    /* 오름차순 기본 정렬 */
    // AA, C, D, F, b, cc
    strStream.sorted(); // 기본 정렬
    strStream.sorted((s1,s2)-> s1.compareTo(s2)); // 람다식
    strStream.sorted(String::compareTo); // 위 문장과 같다.
        
    /* 내림차순 역순 정렬 */
    // cc, b, F, D, C, AA
    strStream.sorted(Comparator.reverseOrder()); // 기본 정렬 역순
    strStream.sorted((s1,s2)-> s2.compareTo(s1)); // 람다식
 
    /* 대소문자 구분 없는 오름차순 정렬 */
    // AA, b, C, cc, D, F
    strStream.sorted(String.CASE_INSENSITIVE_ORDER);
 
    /* 대소문자 구분없는 내림차순 정렬 */
    // F, D, cc, C, b, AA
    strStream.sorted(String.CASE_INSENSITIVE_ORDER.reversed());
 
    /* 길이 순 오름차순 정렬 */
    // b, D, C, F, cc, AA
    // !! 만약 정렬 조건을 추가한다면 .thenComparing()을 붙여 정렬조건을 추가할 수 있습니다.
    strStream.sorted(Comparator.comparing(String::length));
    strStream.sorted(Comparator.comparingInt(String::length)); // no 오토박싱
 
 
    /* 길이 순 내림차순 정렬 */
    // cc, AA, b, D, C, F
    strStream.sorted(Comparator.comparing(String::length).reversed());
  • 변환-map()
	Stream<String> stream = list.stream()
	.map(String::toUpperCase);
	//[A,B,C]
    
    .map(Integers::parseInt);
    // 문자열 -> 정수로 변환

최종 연산

  • Calculating
	IntStream stream = list.stream()
	.count()   //스트림 요소 개수 반환
    .sum()     //스트림 요소의 합 반환
    .min()     //스트림의 최소값 반환
    .max()     //스트림의 최대값 반환
    .average() //스트림의 평균값 반환
  • Reduction
	IntStream stream = IntStream.range(1,5);
	.reduce(10, (total,num)->total+num);
    //reduce(초기값, (누적 변수,요소)->수행문)
    // 10 + 1+2+3+4+5 = 25
  • Iterating
	members.stream()
	.map(Person::getName)
    .forEach(System.out::println);
    //결과를 출력 (peek는 중간, forEach는 최종)
  • Finding
	Person person = members.stream()
					.findAny()   //먼저 찾은 요소 하나 반환, 병렬 스트림의 경우 첫번째 요소가 보장되지 않음
                    .findFirst() //첫번째 요소 반환

참고

https://velog.io/@yun8565/Java-%EC%8A%A4%ED%8A%B8%EB%A6%BCStream-%EC%A0%95%EB%A6%AC
https://hstory0208.tistory.com/entry/Java%EC%9E%90%EB%B0%94-Stream%EC%8A%A4%ED%8A%B8%EB%A6%BC%EC%9D%B4%EB%9E%80

0개의 댓글