Stream

이연중·2021년 1월 29일
0

JAVA

목록 보기
10/20

Stream 소개

stream

  • sequence of elements supporting sequential and parallel aggregate operations
  • 데이터를 담고 있는 저장소(컬렉션)이 아님
  • Functional in nature, 스트림이 처리하는 데이터 소스를 변경하지 않음
  • stream으로 처리하는 데이터는 오직 한번만 처리
  • 무제한일 수도(Short Circuit 메소드를 사용해서 제한할 수 있음)
  • 중개 오퍼레이션은 근본적으로 lazy함(종료 오퍼레이션이 없으면 처리하지 않음)
  • 손쉽게 병렬 처리할 수 있음(데이터가 방대한 경우 parallelStream 사용)

stream 파이프라인

  • 0 또는 다수의 중개 오퍼레이션과 한개의 종료 오퍼레이션으로 구성
  • 스트림의 데이터 소스는 오직 터미널 오퍼레이션을 실행할 때만 처리

중개 오퍼레이션

  • stream을 리턴
  • stateless / stateful 오퍼레이션으로 더 상세하게 구분 가능(대부분 stateless지만 distinct나 sorted처럼 이전 소스 데이터를 참조해야 하는 오퍼레이션은 stateful 오퍼레이션)
  • filter, map, limit, skip, sorted 등

종료 오퍼레이션

  • stream을 리턴하지 않음(stream이 아닌 다른 타입 리턴)
  • collect, allMatch, count, forEach, min, max 등

Stream API 예제

걸러내기

  • Filter(Predicate)
  • 예) 이름이 3글자 이상인 데이터만 새로운 스트림으로

변경하기

  • Map(Function) 또는 FlatMap(Function)
  • 예) 각각의 Post 인스턴스에서 String title만 새로운 스트림으로
  • 예) List<Stream>을 String의 스트림으로

생성하기

  • generate(Supplier) 또는 Iterate(T seed, UnaryOperator)
  • 예) 10부터 1씩 증가하는 무제한 숫자 스트림
  • 예) 랜덤 int 무제한 스트림

제한하기

  • limit(long) 또는 skip(long)
  • 예) 최대 5개의 요소가 담긴 스트림 리턴
  • 예) 앞에서 3개를 뺀 나머지 스트림 리턴

스트림에 있는 데이터가 특정 조건을 만족하는지 확인

  • anyMatch(), allMatch(), nonMatch()
  • 예) k로 시작하는 문자열이 있는지 확인(true 또는 false 리턴)
  • 예) 스트림에 있는 모든 값이 10보다 작은지 확인

개수 세기

  • count()
  • 예) 10보다 큰 수 개수 카운트

스트림을 데이터 하나로 뭉치기

  • reduce(identity, BiFunction), collect(), sum(), max()
  • 예) 모든 숫자 합 구하기
  • 예) 모든 데이터를 하나의 List 또는 Set에 옮겨 담기

예제 풀이
OnlineClass

public class OnlineClass {
    private Integer id;
    private String title;
    private boolean closed;

    public OnlineClass(Integer id, String title, boolean closed) {
        this.id = id;
        this.title = title;
        this.closed = closed;
    }
    
    public void setId(Integer id) {
        this.id = id;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public void setClosed(boolean closed) {
        this.closed = closed;
    }

    public Integer getId() {
        return id;
    }

    public String getTitle() {
        return title;
    }

    public boolean isClosed() {
        return closed;
    }
}

App

public class App {
    public static void main(String[] args) {
        List<OnlineClass> springClasses=new ArrayList<>();
        springClasses.add(new OnlineClass(1,"spring boot",true));
        springClasses.add(new OnlineClass(2,"spring data jpa",true));
        springClasses.add(new OnlineClass(3,"spring mvc",false));
        springClasses.add(new OnlineClass(4,"spring core",false));
        springClasses.add(new OnlineClass(5,"rest api developer",false));
        
        List<OnlineClass> javaClasses=new ArrayList<>();
        javaClasses.add(new OnlineClass(6,"The Java, Test",true));
        javaClasses.add(new OnlineClass(7,"The Java, Code manipulation",true));
        javaClasses.add(new OnlineClass(8,"The Java, 8 to 11",false));

        List<List<OnlineClass>> alwaysEvents=new ArrayList<>();
        alwaysEvents.add(springClasses);
        alwaysEvents.add(javaClasses);

        System.out.println("spring으로 시작하는 수업");
        springClasses.stream()
                .filter(c -> c.getTitle().startsWith("spring"))
                .forEach(c->System.out.println(c.getId()));

        System.out.println("close 되지 않은 수업");
        springClasses.stream()
                .filter(Predicate.not(OnlineClass::isClosed))
                .forEach(o->System.out.println(o.getId()));

        System.out.println("수업 이름만 모아서 스트림 만들기");
        springClasses.stream()
                .map(OnlineClass::getTitle)
                .forEach(System.out::println);

        System.out.println("두 수업 목록에 들어있는 모든 수업 아이디 출력");
        alwaysEvents.stream()
                .flatMap(Collection::stream)
                .forEach(o->System.out.println(o.getId()));

        System.out.println("10부터 1씩 증가하는 무제한 스트림 중에서 10개 빼고 최대 10개까지만");
        Stream.iterate(10,i->i+1)
                .skip(10)
                .limit(10)
                .forEach(System.out::println);

        System.out.println("자바 수업 중에 Test가 들어있는 수업이 있는지 확인");
        boolean test=javaClasses.stream()
                .anyMatch(c->c.getTitle().contains("Test"));
        System.out.println(test);

        System.out.println("스프링 수업 중에 제목이 spring이 들어간 것만 제목만 모아서 List로 만들기");
        List<String> spring=springClasses.stream()
                .filter(o->o.getTitle().contains("spring"))
                .map(OnlineClass::getTitle)
                .collect(Collectors.toList());
        spring.forEach(System.out::println);
    }
}

출력

spring으로 시작하는 수업
1
2
3
4
close 되지 않은 수업
3
4
5
수업 이름만 모아서 스트림 만들기
spring boot
spring data jpa
spring mvc
spring core
rest api developer
두 수업 목록에 들어있는 모든 수업 아이디 출력
1
2
3
4
5
6
7
8
10부터 1씩 증가하는 무제한 스트림 중에서 10개 빼고 최대 10개까지만
20
21
22
23
24
25
26
27
28
29
자바 수업 중에 Test가 들어있는 수업이 있는지 확인
true
스프링 수업 중에 제목이 spring이 들어간 것만 제목만 모아서 List로 만들기
spring boot
spring data jpa
spring mvc
spring core

참고

https://www.inflearn.com/course/the-java-java8

profile
Always's Archives

0개의 댓글