코딩 테스트 준비할 떄 자주 나오던 stream 과 메서드 체이닝 패턴을 익숙하게 하고자 관련된 개념들을
코테에 필요한 수준으로라도 간단히 정리하고 넘어가야겠다. map, mapToObj, toArray, :: 등 익숙한듯 생소한 메서드 패턴들도 이번 기회에 집고 넘어가겠다. (~이제 익숙해질 때도 됐잖아..?)
.
< "이것의 자바다"의 목차 참고>
- 스트림이란?
- 내부 반복자
- 중간 처리와 최종 처리
필터링(걸러내기)매핑(변환)정렬루핑(하나씩 처리)매칭(조건 만족 여부)- 기본 집계
- 커스텀 집계
- 요소
수집- 요소 병렬 처리
기존에는 for 반복문(for-each) 혹은 Iterator를 사용했는데
-> 자바 8 버전 부터는 컬렉션 + 배열 요소들 반복 처리에 스트림을 지원한다. (선택의 폭이 넓어짐)
- 스트림은
내부 반복자-> 병렬 처리에 효율적임- 스트림은
람다식으로 다양한 요소 처리 가능- 스트림은
중간 처리와최종 처리의 파이프 라인 형성 가능

for 문과 Iterator은 컬렉션 요소를 바깥쪽으로 반복해서 가져와 처리함 (외부 반복자)
스트림은 요소 처리를 컬렉션 내부로 주입시켜서 요소를 반복 처리하는 방식임 (내부 반복자)
외부 반복자는 외부로 가져와서 처리하는 코드를 개발자가 명시적으로 구현해야 함
내부 반복자는
람다식이나메서드 참조로 반복처리를 간결하게 추상화할 수 있음

필터링-매핑 중간 스트림 double avg = list.stream() // 스트림 생성
.mapToInt(student -> student.getScore()) // 중간 연산: 점수 추출
.average() // 종단 연산: 평균 계산
.getAsDouble(); // 결과 반환
종단 연산(최종 처리)이 있어야 동작함! (지연처리 때문).stream()과 .mapToInt는 처리 규칙만 정의할 뿐! 

.stream 함수로 스트림 생성 가능 Map에서 .entrySet()으로 컬렉션으로 변환 후 가능배열에서 스트림 얻는 방법
IntStream intStream = Arrays.stream(intArray);
filter()메소드는true를 리턴하는 요소만 필터링 한다!
- (참고) distinct() 함수는 중복 제거용으로 사용
list.stream()
.filter(n->n.startWith("박"))
.forEach(n->System.out.println(n));
Map 활용 아래 참고 (entry방식)Map<String, Integer> map = Map.of("Alice", 90, "Bob", 80, "Charlie", 70);
map.entrySet().stream()
.filter(entry -> entry.getValue() >= 80) // 매개변수 entry는 Map.Entry<K, V> 타입
.forEach(entry ->
System.out.println(entry.getKey() + ": " + entry.getValue()))
요소를 다른 요소로 변환하는 중간 처리 기능!
mapXxx(), asDoubleStream(), boxed()등이 있다.

매개 타입
Function은 함수형 인터페이스임!
📌모든Function은 매개값을 리턴값으로매핑(변환)하는applyXxx()메소드를 가지고 있다..!!!
Function<T,R>을 람다식으로 표현하면 아래와 같다.
T -> { return R; }
T -> R;
studentList.steram()
.mapToInt(s->s.getScore)
.forEach(score -> System.out.prinln(score));
flatMapXxx()메소드는 하나의 요소를 복수 개의 요소들로 변환한 새로운 스트림을 리턴한다.

요소를 오름차순 또는 내림차순으로 정렬하는 중간 처리 기능이다.

Comparable (함수형) 인터페이스의 compareTo 함수를 구현(오버라이딩)하고 있어야만 sorted 메소드 사용 가능객체(요소)가 Comparable 인터페이스를 구현하고 있지 않다면 비교자(Comparator 인터페이스를 구현한 객체)를 제공하면 된다.
sorted((n1,n2) -> {n2-n1}이런식으로 간단히 람다식으로 작성하면 됨
루핑은 스트림에서 요소를 하나씩 반복해서 가져와서 처리하는 것을 말함
루핑 메소드엔peek()와forEach()가 있다.

peek()는 중간 처리 메소드이고 forEach는 최종 처리 메소드 이다.Consumer은 함수형 인터페이스 이고 아래과 같다.
매칭은 요소들이 특정 조건에 만족 하는지 여부를 조사하는
최종 처리 기능이다.


집계(Aggregate)는 카운팅, 합계, 평균값, 최대값 등과 같이 하나의 값으로 산출하는 것을 말함
-> 대량의 데이터를 하나의 값으로 축소하는 리덕션

OptionalXXX는 최종값을 저장하는 객체로 get(), getAsDouble(), getAsInt()를 호출하면 최종값을 얻을 수 있다.Optional null값을 표현하기 위해 사용 됨!!count() 랑 sum()은 null값이 있을 수가 없기 때문에 사용하지 않는 거네~double avg = Arrays.stream(arr)
.filter(n -> n % 2 == 0)
.average()
.getAsDouble();
long count = Arrays.stream(arr)
.filter(n -> n%2 ==0)
.count();


reduce()로 다양한 집계 결과물을 만들 수 있다.


getAsXXX()가 필요 없음 (null값 반환이 필요 없으니깐)필터링 또는 매핑 한 후 요소들을 수집하는 최종 처리 메소드
-> 필요한 요소만 컬렉션에 담을 수 있고 그룹핑 한 후 집계도 가능함

List<Student> maleList = totalList.stream()
.filter(s->s.getSex().equals("남"))
.collect(Collectors.toList());
함수형 인터페이스를 구현한 객체를 파라미터로 가지는 함수!