The Java8(Stream API)
Stream API
Stream API 사용 예제
걸래내기
- Filter(Predicate)
- 예) 이름이 3글자 이상인 데이터만 새로운 스트림으로
변경하기
- Map(Funtion)또는 FlatMap(Function)
- 예) 각각의 Post 인스턴스에서 String title만 새로운 스트림으로
- 예) List<Stream
>을 String의 스트림으로
생성하기
- generate(Supplier)또는 lterate(T seed, UnaryOperator)
- 예) 10부터 1씩 증가하는 무제한 숫자 스트림
- 예)랜덤 int 무제한 스트림
제한하기
- limit(long)또는 skip(long)
- 예) 최대 5개의 요소가 담긴 스트림을 리턴한다.
- 예) 앞에서 3개를 뺀 나머지 스트림을 리턴한다.
스트림에 있는 데이터가 특정 조건을 만족하는지 확인
- anyMatch(), allMatch(), nonMatch()
- 예) k로 시작하는 문자열이 있는지 확인한다. (true 또는 false를 리턴한다.)
- 예) 스트림에 있는 모든 값이 10보다 작은지 확인한다.
- 개수 세기
- count()
- 예) 10보다 큰 수의 개수를 센다.
- count()
- reduce(identity, BiFunction), collect(), sum(), max()
- 예) 모든 숫자 합 구하기
- 예) 모든 데이터를 하나의 List 또는 Set에 옮겨 담기
연습
- OnlineClass
@Getter@Setter
public class OnlineClass {
private Integer id;
private String title;
private boolean closed;
public Progress progree;
public OnlineClass(Integer id, String title, boolean closed) {
this.id = id;
this.title = title;
this.closed = closed;
}
}
- SpringPractice
public class SpringPractice {
public static void main(String[] args) {
List<OnlineClas> springClasses = new ArrayList<>();
springClasses.add(new OnlineClass(1, "spring boot", true));
springClasses.add(new OnlineClass(2, "spring data jap", true));
springClasses.add(new OnlineClass(3, "spring mvc", false));
springClasses.add(new OnlineClass(4, "spring core", false));
springClasses.add(new OnlineClass(5, "rest api development", 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", true));
List<List<OnlineClass>> danteEvents = new ArrayList<>();
System.out.println("spring으로 시작하는 수업");
System.out.println("close 되지 않은 수업");
System.out.println("수업 이름만 모아서 스트림 만들기");
System.out.println("두 수업 목록에 들어있는 모든 수업 아이디 출력");
System.out.println("10부터 1씩 증가하는 무제한 스트림 중에서 앞에 10개 빼고 최대 10개 까지만");
System.out.println("자바 수업 중에 Test가 들어있는 수업이 있는지 확인");
System.out.println("스프릥 수업 중에 제목에 spring이 들어간 것만 모아서 List로 만들기");
}
}
- 출력하기 : spring으로 시작하는 수업을 id로 출력하세요
springClasses.stream().filter(oc -> oc.getTitle().startsWith("spring")
.forEach(oc -> System.out.println(oc.getId())));
springClasses에서 stream()에 filter를 이용해서 출력한다.
oc 매개변수 oc.getTitle() 제목에서 “spring”으로 시작하는 것. forEach로 출력해준다.
- 출력하기 : close 되지 않은 수업
springClasses.stream().filter(oc -> !oc.isClosed())
.forEach(oc -> System.out.println(oc.getId());
조금 더 단축하는 방법 : 메소드 레퍼런스, interface에 있는 static 메소드 활용해서 단축
OnlineClass에 isClosed가 있다. 임의에 객체에 인스턴스 참조하는 방법 사용
springClasses.stream()
.filter(Predicate.not(OnlineClass::isClosed)) //임의 객체에 인스턴스메소드 참조하는 방법 -> 메소드 컨퍼런스 참고
.forEach(oc -> System.out.println(oc.getId()));
- 출력 : 수업 이름만 모아서 스트림 만들기
map() 중개형 오퍼레이터를 사용한다.
springClasses.stream()
.map(oc -> oc.getTitle()) //map은 들어올떄는 oc-> stream() 다른타입->
.forEach(s -> System.out.println(s)); //forEach에서는 String 타입으로 들어온다.
method reference로 구현
springClasses.stream()
.map(OnlineClass::getTitle)
.forEach(System.out::println);
- 출력하기 : 두 수업 목록에 들어 있는 모든 수업 아이디 출력
danteEvents.stream()
.flatMap(list -> list.stream())
.forEach(oc -> System.out.println(oc.getId()));
Operator안에 들어오는 현재 타입이 뭔지를 항상 인지하고 있어야한다.
flatMap 이란?
method reference로 구현
danteEvents.stream()
.flatMap(Collection::stream)
.forEach(oc -> System.out.println(oc.getId()));
- 출력 : 10부터 1씩 증가하는 무제한 스트림 중에서 아펭 10개 빼고 최대 10개 까지만
Stream.iterate(10, i -> i + 1) // seed는 10부터 하라는 것 i -> i + 1; 1씩 증가
.skip(10) // 처음 10개는 skip하고
.limit(10) // 최대 10개까지만
.forEach(System.out::println); // 출력
출력
20
21
22
23
24
25
26
27
28
29
- 출력 :자바 수업 중에 Test가 들어있는 수업이 있는지 확인
- anyMatch : 종료형 Operator Match하는지 확인한다.
- AllMatch
booleantest = javaClass.stream().anyMatch(oc->oc.getTitle().contains("Test"));
System.out.println(test);
- 출력 : 스프링 수업 중에 제목에 spring이 들어간 제목만 모아서 List로 만들기
List<String> spring = springClasses.stream().filter(oc->oc.getTitle().contains("spring"))
.map(OnlineClass::getTitle) // 제목만 모아야하니깐 map으로 하고
.collect(Collectors.toList()); // collect로 toList()로 만들어준다.
spring.forEach(System.out::println);
주의 : 순서를 바꾸면 지나가는 타입이 바뀐다.
map(OnlineClass를받고 ) → OnlineClass를 문자열로 바꿨다. → filter(문자열을 받고)
List<String> spring2 = springClasses.stream()
.map(OnlineClass::getTitle)// .map(oc -> oc.getTitle())
.filter(t->t.contains("spring"))
.collect(Collectors.toList());
spring2.forEach(System.out::println);
Stream API를 배우며…. 느낀점
정말 어렵다… stream ㅠㅠ 그래도 꾸준히 하다가 보면 실력은 늘기마련 … 진짜 감이 잘 안온다. 익숙하지 않아서인가? java8은 정말 어렵다~
천천히 slowly~~~~!!
하나하나 차근차근해보자 ! 계속 도전!