본 게시물은 인프런 백기선님 강의 "더 자바, java8"을 학습하고 개인적으로 정리한 내용입니다.
https://www.inflearn.com/course/the-java-java8#
목차
1. 스트림 소개
2. 스트림 API
1. 스트림 소개
스트림은 연속된 데이터를 처리하는 operation의 모임이다. 데이터의 저장소(컬렉션)이 아니다. 컬렉션이 데이터를 가지고 있는 것이고 stream은 data를 소스로 사용해서 처리하는 것이다.
스트림의 특징
- Functional in nature
- 무제한일 수도 있지만 Short Circuit 메소드를 사용해서 제한할 수 있다.
- 중계 오퍼레이션은 근본적으로 lazy하다.
Functional in nature
functional의 중요한 의미는 source를 변경하지 않는다는 것이다. 예를 들어 names.stream()을 하면 stream을 얻어낼 수 있는데 그 뒤에 map 등 operation을 사용하면 그 결과가 또 다른 stream이 되는 것이지 stream으로 전달 받은 데이터 자체가 변경된다는 것은 아니다.
public class App {
public static void main(String[] args) {
List<String> names = new ArrayList<>();
names.add("keesun");
names.add("whiteship");
names.add("toby");
names.add("foo");
Stream<String> stringStream = names.stream().map(String::toUpperCase);
names.forEach(System.out::println);
}
}
중계 오퍼레이션은 근본적으로 lazy하다.
스트림에 사용하는 여러메소드가 있는데 크게 두가지로 나눌 수 있다.
- 중계 operator : 계속해서 이어진다. stream을 반환한다.
- 터미널 operator : 스트림을 끝낼 때 사용한다. stream이 아닌 다른 것을 반환한다.
중계 operator는 터미널 operator가 오기전까지 실행하지 않는다. 중간에 print를 해도 실행되지 않는다.
public class App {
public static void main(String[] args) {
List<String> names = new ArrayList<>();
names.add("keesun");
names.add("whiteship");
names.add("toby");
names.add("foo");
names.stream().map((s) -> {
System.out.println(s);
return s.toUpperCase();
});
System.out.println("=======");
names.forEach(System.out::println);
}
}
위 코드를 실행하면 "======="가 출력되기 전에 아무것도 출력되지 않는다.
중계 operator는 여러개를 사용할 수 있지만 반드시 종료형 operator가 나와야한다. 종료형 operator가 실행되기 전까지 중계전 operator는 무의미하다. 만약 다음과 같이 collect(Collectors.toList())를 사용하면
public class App {
public static void main(String[] args) {
List<String> names = new ArrayList<>();
names.add("keesun");
names.add("whiteship");
names.add("toby");
names.add("foo");
List<String> collect = names.stream().map((s) -> {
System.out.println(s);
return s.toUpperCase();
}).collect(Collectors.toList());
System.out.println("=======");
names.forEach(System.out::println);
}
}
"=======" 가 출력되기 전과 후 모두 name이 출력된다.
스트림 API
예제 코드
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 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", false));
List<List<OnlineClass>> keesunEvents = new ArrayList<>();
keesunEvents.add(springClasses);
keesunEvents.add(javaClasses);
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로 만들기");
}
}
1. spring으로 시작하는 수업
springClasses.stream().filter(c -> c.getTitle().startsWith("spring"))
.forEach(c ->System.out.println(c.getId()));
2. close 되지 않은 수업
springClasses.stream().filter(Predicate.not(OnlineClass::isClosed))
.forEach(c -> System.out.println(c.getId()));
OnlineClass에 isNotClosed()를 만드는 방법도 있겠지만, 이미 존재하는 Predicate.not의 기본메서드를 사용하는 것도 좋은 방법인 것 같다.
3. 수업 이름만 모아서 스트림 만들기
springClasses.stream()
.map(c->c.getTitle())
.forEach(System.out::println);
4.두 수업 목록에 들어있는 모든 수업 아이디 출력
keesunEvents.stream().flatMap(Collection::stream)
.forEach(c->System.out.println(c.getId()));
flatlMap을 사용하면 입력받는 여러 스트림을 하나의 스트림으로 합칠 수 있다.
5. 10부터 1씩 증가하는 무제한 스트림 중 앞에 10개 빼고 최대 10개까지만
Stream.iterate(10, i-> i + 1)
.skip(10)
.limit(10)
.forEach(System.out::println);
6. 자바 수업 중에 Test가 들어있는 수업이 있는지 확인
boolean test = javaClasses.stream().anyMatch(c -> c.getTitle().contains("Test"));
System.out.println(test);
7. 스프링 수업 중에 제목에 spring이 들어간 것만 모아서 List로 만들기
List<String> spring = springClasses.stream()
.filter(c->c.getTitle().contains("spring"))
.map(OnlineClass::getTitle)
.collect(Collectors.toList());
spring.forEach(System.out::println);
'자바 > 백기선 더 자바, java8' 카테고리의 다른 글
[더 자바, java8] Optional 소개 (0) | 2022.11.20 |
---|---|
[더 자바, java8] 인터페이스의 변화 (0) | 2022.11.15 |
[더 자바, java8] 함수형 인터페이스와 람다 (0) | 2022.11.02 |