본 게시물은 인프런 백기선님 강의 "더 자바, java8"을 학습하고 개인적으로 정리한 내용입니다.
https://www.inflearn.com/course/the-java-java8#
더 자바, Java 8 - 인프런 | 강의
자바 8에 추가된 기능들은 자바가 제공하는 API는 물론이고 스프링 같은 제 3의 라이브러리 및 프레임워크에서도 널리 사용되고 있습니다. 이 시대의 자바 개발자라면 반드시 알아야 합니다. 이
www.inflearn.com
목차
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 |