티스토리 뷰
필터링
Predicate로 필터링
스트림 인터페이스 중 filter 메서드는 Predicate(불리언을 반환하는 함수)를 인수로 받아서 Predicate와 일치하는 모든 요소를 포함하는 스트림을 반환한다.
List<Dish> vegetarianMenu = menu.stream()
.filter(Dish::isVegetarian) //채식 요리인지 확인하는 메서드 참조
.collect(toList());
고유 요소 필터링
스트림은 고유 요소로 이루어진 스트림을 반환하는 distinct 메서드도 지원한다.
List<Integer> numbers = Arrays.asList(1, 2, 1, 3, 3, 2, 4);
numbers.stream()
.filter(i -> i%2 ==0)
.distinct()
.forEach(System.out::println);
스트림 축소
스트림은 주어진 값 이하의 크기를 갖는 새로운 스트림을 반환하는 limit(n) 메서드를 지원한다.
스트림이 정렬되어 있으면 최대 요소 n개를 반환할 수 있다.
List<Dish> dishes = specialMenu.stream()
.filter(d -> d.getCalories() > 300)
.limit(3)
.collect(toList());
만약 정렬되어 있지 않으면 limit의 결과도 정렬되지 않은 상태로 반환된다.
요소 건너뛰기
스트림은 처음 n개 요소를 제외한 스트림을 반환하는 skip(n) 메서드를 지원한다.
만약 n개 이하의 스트림의 요소에서 skip(n)을 호출하면 빈 스트림이 반환된다.
List<Dish> dishes = menu.stream()
.filter(d -> d.getCalories() > 300)
.skip(2)
.collect(toList());
매핑
스트림의 각 요소에 함수 적용하기
스트림은 함수를 인수로 받는 map 메서드를 지원한다. 인수로 제공된 함수는 각 요소에 적용되며 함수를 적용한 결과가 새로운 요소로 매핑된다.
List<String> dishNames = menu.stream()
.map(Dish::getName)
.collect(toList());
System.out.println(dishNames);
단어리스트가 주어졌을 때 각 단어가 포함하는 글자 수의 리스트를 반환한다고 하면?
List<String> words = Arrays.asList("Hello", "World");
List<Integer> wordLengths = words.stream()
.map(String::length)
.collect(toList());
System.out.println(wordLengths);
스트림 평면화
리스트에서 고유 문자로 이루어진 리스트를 반환해보자
[”Hello”, “World”] → 기대값은 [”H”, “e”, “l”, “o”, “W”, “r”, ”d”]
words.stream()
.map(word -> word.split(""))
.distinct()
.forEach(System.out::println);
위 코드에서 map으로 전달한 람다는 Stream<String[]> 이 된다.
스트림을 평면화 하기 위해서 flatMap 사용
words.stream()
.map(word -> word.split("")) //각 단어를 개별 문자를 포함하는 배열로 변환
.flatMap(Arrays::stream) //생성된 스트림을 하나의 스트림으로 평면화
.distinct()
.forEach(System.out::println);
flatMap 메서드는 스트림의 각 값을 다른 스트림으로 만든 다음에 모든 스트림을 하나의 스트림으로 연결하는 기능을 수행한다.
검색과 매칭
anyMatch - 스트림에서 적어도 한 요소와 일치하는지 확인할 때 사용
//menu에 채식요리가 있는지 확인
menu.stream().anyMatch(Dish::isVegetarian)
allMatch - 스트림의 모든 요소가 주어진 프레디케이트와 일치하는지 검사
//모든 요리가 1000칼로리 밑인지 검사
menu.stream().allMatch(dish -> dish.getCalories() < 1000);
nonMatch - allMatch의 반대
위의 세 메서드는 스트림 쇼트서킷 기법 연산을 활용한다.
요소 검색
findAny - 스트림에서 임의의 요소를 반환
Optional<Dish> dish = menu.stream().filter(Dish::isVegetarian).findAny();
요소가 없을 수도 있기 때문에 Optional로 반환된다.
첫 번째 요소 찾기
findFirst - 스트림 요소에서 첫 번째 요소를 반환
//숫자 3으로 나누어 떨어지는 첫 번째 제곱값을 반환.
List<Integer> someNumbers = Arrays.asList(1, 2, 3, 4, 5);
Optional<Integer> firstSquareDivisibleByThree = someNumbers.stream()
.map(n -> n * n)
.filter(n -> n % 3 == 0)
.findFirst();
숫자형 스트림
Stream은 숫자 스트림을 효율적으로 처리할 수 있도록 기본형 특화 스트림을 제공한다.
기본형 특화 스트림
스트림 API는 박싱 비용을 피할 수 있도록 3가지 기본형 특화 스트림을 제공한다.
IntStream, DoubleStream, LongStream
특화 스트림은 오직 박싱 과정에서 일어나는 효율성과 관련있으며 스트림에 추가 기능을 제공하지는 않는다.
int calories = menu.stream() //Stream<Dish> 반환
.mapToInt(Dish::getCalories) //IntStream 반환
.sum();
System.out.println("Number of calories:" + calories);
mapToInt 메서드가 IntStream을 반환하므로 IntStream 인터페이스에서 제공하는 sum 메서드를 사용할 수 있다. 만약 스트림이 비어있으면 sum은 기본값 0을 반환한다.
객체 스트림으로 복원하기
boxed 메서드를 이용해서 특화 스트림을 일반 스트림으로 변환할 수 있다.
IntStream intStream = menu.stream().mapToInt(Dish::getCalories); //숫자 스트림 변환
Stream<Integer> stream = intStream.boxed(); //숫자 스트림을 스트림으로 변환
Optional 도 OptionalInt, OptionalDouble, OptionalLong 세 가지 기본형 특화 스트림 버전도 제공한다.
숫자 범위
특정 범위의 숫자를 이용할 때는 IntStream과 LongStream에서 range와 rangeClosed 정적 메서드를 사용할 수 있다.
range 메서드는 시작값과 종료값이 결과에 포함되지 않는 반면 rangeClosed는 시작값과 종료값이 결과에 포함된다.
IntStream evenNumbers = IntStream.rangeClosed(1, 100); //시작값 종료값 포함
System.out.println(evenNumbers.count()); //50
스트림 만들기
값으로 스트림 만들기
임의의 수를 인수로 받는 정적 메서드 Stream.of을 이용해서 스트림을 만들 수 있다.
Stream<String> stream = Stream.of("Modern", "Java", "In", "Action");
stream.map(String::toUpperCase).forEach(System.out::println);
null이 될 수 있는 객체로 스트림 만들기
자바 9에서는 null이 될 수 있는 개체를 스트림으로 만들 수 있는 새로운 메서드가 추가
Stream<String> homeValueStream = Stream.ofNullalbe(System.getProperty("home"));
Stream<String> values = Stream.of("config", "home", "user")
.flatMap(key -> Stream.ofNullable(System.getProperty(key));
배열로 스트림 만들기
배열을 인수로 받는 정적 메서드 Arrays.stream을 이용해서 스트림을 만들 수 있다.
int[] numbers = {2,3,5,7,11,13};
int sum = Arrays.stream(numbers).sum();
파일로 스트림 만들기
자바의 NIO API도 스트림 API를 활용할 수 있도록 업데이트 되었다.
long uniqueWords = 0;
try(Stream<String> lines = Files.lines(Paths.get("data.txt"), Charset.defaultCharset()) {
uniqueWords = lines.flatMap(line -> Arrays.stream(line.split(" ")))
.distinct()
.count();
} catch(IOException e) {}
Stream 인터페이스는 AutoCloseable 인터페이스를 구현한다.
- Total
- Today
- Yesterday
- localtime
- Kotlin
- oracle
- jQuery
- 북리뷰
- 베리 심플
- Spring Security
- docker
- Github Status
- intellij
- JavaScript
- input
- k8s
- rocky
- mybatis
- Spring
- LocalDate
- Linux
- mybatis config
- Java
- 오라클
- config-location
- LocalDateTime
- svn
- maven
- Bash tab
- elasticsearch
- window
- springboot
- Mac
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |