14-40~44 스트림의 최종연산

oyeon·2021년 3월 22일
0

Java 개념

목록 보기
70/70

forEach(), forEachOrdered()

  • 스트림의 모든 요소에 지정된 작업을 수행 - forEach(), forEachOrdered()
// 병렬 스트림인 경우 순서가 보장되지 않음
void forEach(Consumer<? super T> action) 

// 병렬 스트림인 경우에도 순서가 보장됨
void forEachOrdered(Consumer<? super T> action)

sequential() - 직렬 스트림

  • 기본적으로 직렬 스트림이므로 생략해도 동일
// 123456789
IntStream.range(1, 10).sequential().forEach(System.out::print);
IntStream.range(1, 10).forEach(System.out::print); // 위와 동일
// 123456789
IntStream.range(1, 10).sequential().forEachOrdered(System.out::print);
IntStream.range(1, 10).forEachOrdered(System.out::print); // 위와 동일

parallel() - 병렬 스트림

  • 병렬 스트림에서 forEach의 경우 순서 보장이 안됨
  • 순서 보장을 위해서는 forEachOrdered 사용
// 683295714
IntStream.range(1, 10).parallel().forEach(System.out::print);
// 123456789
IntStream.range(1, 10).parallel().forEachOrdered(System.out::print);

조건 검사

조건 검사 - allMatch(), anyMatch(), noneMatch()

// 모든 요소가 조건을 만족시키면 true
boolean allMatch(Predicate<? super T> predicate)
// 한 요소라도 조건을 만족시키면 true
boolean anyMatch(Predicate<? super T> predicate)
// 모든 요소가 조건을 만족시키지 않으면 true
boolean noneMatch(Predicate<? super T> predicate)
// 낙제자가 있는지?
boolean hasFailedStu = stuStream.anyMatch(s -> s.getTotalScore() <= 100);

조건에 일치하는 요소 찾기 - findFirst(), findAny()

Optional<T> findFirst()	// 첫 번째 요소를 반환. 순차 스트림에 사용
Optional<T> findAny()	// 아무거나 하나를 반환. 병렬 스트림에 사용
Optional<Student> result = stuStream.filter(
		s -> s.getTotalScore() <= 100).findFirst();
Optional<Student> result = parallelStream.filter(
		s -> s.getTotalScore() <= 100).findAny();

reduce() (중요)

  • 스트림의 요소를 하나씩 줄여가며 누적연산(accumulator) 수행
Optional<T> reduce(BinaryOperator<T> accumulator)
T 	    reduce(T identity, BinaryOperator<T> accumulator) (핵심)
U 	    reduce(U identity, BiFunction<U,T,U> accumulator,
					BinaryOperator<U> combiner)
identity	- 초기값
accumulator	- 이전 연산결과와 스트림의 요소에 수행할 연산
combiner	- 병렬처리된 결과를 합치는데 사용할 연산(병렬 스트림)
// int reduce(int identity, IntBinaryOperator op)
int count = intStream.reduce(0, (a, b) -> a + 1); // count()
int sum = intStream.reduce(0, (a, b) -> a + b);   // sum()

// max()
int max = intStream.reduce(Integer.MIN_VALUE, (a, b) -> a > b ? a : b);

// min()
int min = intStream.reduce(Integer.MAX_VALUE, (a, b) -> a < b ? a : b);

위의 sum()은 내부적으로 아래와 같이 동작한다.
(이것만 정확히 이해하면 된다.)

int a = 0; // int a = identity;
for(int b : stream)
	a = a + b;	// sum()

실습

public static void main(String[] args){
	String[] strArr = {
    	"Inheritance", "Java", "Lambda", "stream",
        "OptionalDouble", "IntStream", "count", "sum"
    };
    
    Stream.of(strArr).parallel().forEachOrdered(System.out::println);
    
    boolean noEmptyStr = Stream.of(strArr).noneMatch(s->s.length() == 0);
    Optional<String> sWord = Stream.of(strArr).parallel()
    				.filter(s->s.charAt(0)=='s').findAny();
    
    System.out.println(noEmptyStr);
    System.out.println(sWord);
    
    // Stream<String>을 Stream<Integer>로 변환
    // String::length == (s) -> s.length()
    Stream<Integer> intStream = Stream.of(strArr).map(String::length);
    
    // Stream<String>을 IntStream으로 변환. IntStream은 기본형 스트림.
    // 최종 연산은 한 번밖에 쓰지 못하므로 여러 스트림을 생성
    IntStream intStream1 = Stream.of(strArr).mapToInt(String::length);
    IntStream intStream2 = Stream.of(strArr).mapToInt(String::length);
    IntStream intStream3 = Stream.of(strArr).mapToInt(String::length);
    IntStream intStream4 = Stream.of(strArr).mapToInt(String::length);
    
    int count = intStream1.reduce(0, (a, b) -> a + 1);
    int sum   = intStream2.reduce(0, (a, b) -> a + b);
    
    OptionalInt max = intStream3.reduce(Integer::max);
    OptionalInt min = intStream4.reduce(Integer::min);
    
    System.out.println(count);
    System.out.println(sum);
    
    // max 값이 비어있으면 예외를 발생하므로 get방식보다는 orElse를 쓰자.
    System.out.println(max.getAsInt()); // 비추
    System.out.println(min.getAsInt()); // 비추
    
    // 이 방식을 많이 사용
    System.out.println(max.orElse(0)); // 결과가 없으면 0 반환
    System.out.println(min.orElseGet(()->0)); // 결과가 없으면 0 반환
    
profile
Enjoy to study

0개의 댓글