자바 8 스트림 api
DESCRIPTION
Java 8 Steam APITRANSCRIPT
Java 8 Stream APIA different way to process collections
09:18:24
나즈혼
람다기본메서드
STREAM API날짜 API
동시성 개선
Base 64
메타프로그래밍 향상
자바스크립트 엔진
2014.3 현재 버전 8.25
09:18:25
List transactionIds = new ArrayList(); for (Transaction t : groceryTransactions) {
transactionIds.add(t.getId()); }
Collections.sort(groceryTransactions, new Comparator() { public int compare(Transaction t1, Transaction t2) {
return t2.getValue().compareTo(t1.getValue()); }
});
List groceryTransactions = new ArrayList(); for (Transaction t : groceryTransactions) {
if (t.getType() == Transaction.GROCERY) { groceryTransactions.add(t);
} }
Java 코드로 구매내역 구하기
식료품점에서 구매한걸 찾고
사용 금액 순으로 정렬한 뒤
거래 내역의 ID를 추출
09:18:25
그럼 Database에서는?
SELECT id FROM TRANSACTIONSWHERE type = ‘GROCERY’ ORDER BY value DESC
별도의 작업 없이 이미 등록된 집계 함수를 사용
SUM, MAX, COUNT, AVG 등등
09:18:25
List groceryTransactions = new ArrayList(); for (Transaction t : groceryTransactions) {
if (t.getType() == Transaction.GROCERY) { groceryTransactions.add(t);
} }
Collections.sort(groceryTransactions, new Comparator() { public int compare(Transaction t1, Transaction t2) {
return t2.getValue().compareTo(t1.getValue()); }
});
List transactionIds = new ArrayList(); for (Transaction t : groceryTransactions) {
transactionIds.add(t.getId()); }
다시 한번 자바 코드
길다!
복잡하다!
코딩해야된다!09:18:25
그래서 준비 했습니다!
List transactionsIds = transactions.stream()
.filter(t -> t.getType() == Transaction.GROCERY)
.sorted(Comparator.comparing(Transaction::getValue).reversed())
.map(Transaction::getId)
.collect(Collectors.toList());
람다 표현식
메소드 참조
09:18:25
일반적인 스트림의 흐름
filter sorted map collecttransactions
2. 중간 작업 (Intermediate Operations)
PipeLine1. 데이터소스
3. 종료 작업 (Terminal Operations)
09:18:25
중간 작업 및 종료 작업
중간 작업(Intermediate Operations)
• 항상 스트림을 리턴• Pipeline 형태로 연결 시킬 수 잇음• 데이터를 처리하기 위한 로직• 직접 처리를 시작 할 수는 없음
• 오브젝트를 리턴 하거나, collection 또는 void 리턴 가능• Pipeline으로 구성된 작업을 시작• 한번 수행되고 난 후에 작업한 스트림에 재작업 불가능
종료 작업(Terminal Operations)
flatMap
map
distinct
sorted
limitpeek
filterforeach
skip
toArray
reduce
collect
minmaxcount
anyMatchallMatchnoneMatchfirstFind
anyFind
09:18:25
좀 더 상세히Id : 1
Value : 100Id : 3
Value : 80Id : 6
Value : 120Id : 10
Value : 50Id : 7
Value : 40Stream <Transaction)
Id : 3Value : 80
Id : 6Value : 120
Id : 10Value : 50
.filter(t -> t.getType() == Transaction.GROCERY)
Stream <Transaction)
Id : 6Value : 120
Id : 3Value : 80
Id : 10Value : 50
.sorted(Comparator.comparing(Transaction::getValue).reversed())
Stream <Transaction)
6 3 10.map(Transaction::getId) Stream <Integer)
6 3 10
.collect(Collectors.toList()); List<Integer)
09:18:25
Stream API• Java.util.stream• 연산의 선언적 서술
• 반복 구조 캡슐화, 알고리듬 분리• 제어 흐름 추상화
• 함수형 방식 처리 : 데이터 불변• 지연 처리, 대부분의 작업을 단일 반복 수행으로 처리• 무한 연속 데이터 흐름 API• 다양한 데이터 원천 지원: 컬렉션, 생성 메서드, 파일 I/O 등
09:18:25
컬렉션과 스트림
스트림
컬렉션
List Map Set
보관형 자료구조
데이터 처리 추상화
09:18:25
스트림과 컬렉션 처리 방법의 차이
• 파이프라이닝(Pipelining)• 많은 스트림의 기능들이 스트림 자기 자신을 리턴• 처리 작업이 체인처럼 연결되어 큰 파이프라인처럼 동작 하도록 함
• 내부 반복(Internal Iteration)• 명시적으로 반복작업을 수행해야되는 컬렉션과 달리 스트림 작업은 내부에서 처리
09:18:25
잠시 중간 정리
1. 질의를 할 데이터소스(Collection 같은)가 필요2. 파이프라인을 형성하는 중간 작업(Intermediate Operations)3. 파이프라인을 실행하고 결과를 리턴하는 종료 작업(Terminal
Operations)
Stream 을 사용하는 일반적인 3가지 내용
09:18:25
java.util.stream
• Building Streams• Infinite Streams• Numeric Streams• Filtering• Mapping• Finding and matching• Reducing• Collect
09:18:25
Building Streams
Stream<Integer> numbersFromValues = Stream.of(1, 2, 3, 4); int[] numbers = {1, 2, 3, 4};
IntStream numbersFromArray = Arrays.stream(numbers);
long numberOfLines = Files.lines(
Paths.get(“yourFile.txt”), Charset.defaultCharset()).count();
Collection, 숫자들, 값 목록, 배열, 파일
값 목록, 배열에서 Stream 생성
파일에서 Stream 생성
09:18:25
Infinite StreamsStream<Integer> numbers = Stream.iterate(0, n -> n + 10);
numbers.limit(5).forEach(System.out::println); // 0, 10, 20, 30, 40
Stream.iterate
Stream.generate
09:18:25
Numeric Streamsint statement = transactions.stream()
.map(Transaction::getValue)
.sum(); // error since Stream has no sum method
int statementSum = transactions.stream()
.mapToInt(Transaction::getValue)
.sum(); // works!
IntStreamDoubleStreamLongStream
mapToIntmapToDoublemapToLong
sum(), min(), max(), average(), count()
int statementSum = transactions.stream() .mapToInt(Transaction::getValue)
.IntSummaryStatistics();
// IntSummaryStatistics{count=7, sum=28, min=1, average=4.000000, max=7}
09:18:25
Filtering
• filter • 주어진 predicate와 일치하는 stream을 리턴
• distinct• 중복을 제거한 유니크 엘리먼트 stream을 리턴
• limit(n)• 주어진 사이즈(n) 까지의 stream을 리턴
• skip(n)• 주어진 엘리먼트 길이 까지 제외한 stream을 리턴
09:18:25
MappingList<String> words = Arrays.asList("Oracle", "Java", "Magazine"); List<Integer> wordLengths = words.stream()
.map(String::length)
.collect(toList());
map(String::length) 인자로 전달 받은 값들을 가지고 새로운 Stream 생성
List에 저장된 단어들의 길이를 가지고 있는 새로운 list 생성
map(e -> e * 2) map(s -> s.toUpperCase())
09:18:25
Finding and Matching
transactions.stream() .filter(t -> t.getType() == Transaction.GROCERY) .findAny()
.ifPresent(System.out::println);
boolean expensive = transactions.stream()
.allMatch(t -> t.getValue() > 100);
anyMatch, allMatch, noneMatch
Optional<Transaction> = transactions.stream().filter(t -> t.getType() == Transaction.GROCERY)
.findAny();
findFirst, findAny
java.util.Optional
09:18:25
Reducingint sum = 0; for (int x : numbers) { sum += x; }
int sum = numbers.stream().reduce(0, (a, b) -> a + b);
int product = numbers.stream().reduce(1, (a, b) -> a * b);
int product = numbers.stream().reduce(1, Integer::max);
for loop 를 활용한 덧셈
초기화 값 : 0BinaryOperator<T> : 두개의 엘리멘트를 더해 새로운 값을 생성
모든 값을 곱하기
최대값 구하기
엘리먼트들을 하나의 결과로 추출
09:18:25
Collect
09:18:25
List<Person> filtered = persons .stream() .filter(p -> p.name.startsWith("P"))
.collect(Collectors.toList()); // Collectors.toSet()
System.out.println(filtered); // [Peter, Pamela]
Map<Integer, List<Person>> personsByAge = persons .stream()
.collect(Collectors.groupingBy(p -> p.age));
personsByAge .forEach((age, p) -> System.out.format("age %s: %s\n", age, p));
// age 18: [Max] // age 23: [Peter, Pamela] // age 12: [David]
정리1.Stream API 의 다양한 기능을 활용해 데이터 처리를 최적화 할 수 있다.2.람다와 메서드 참조를 알아 두면 더 좋음!3.병렬 처리를 손쉽게 지원
• stream() -> parallelStream()
09:18:25
참고자료1. Processing Data with Java SE 8 Streams
• http://www.oracle.com/technetwork/articles/java/ma14-java-se-8-streams-2177646.html
2. Beyond Java : 자바 8을 중심으로 본 자바의 혁신• http://www.slideshare.net/gyumee/beyond-java-8
3. java.util.stream• https://docs.oracle.com/javase/8/docs/api/java/util/stream/package-summary.html
THANK YOU!
09:18:25