파이프 라인(Pipe Line)
파이프 라인(Pipe Line)
- 스트림(Stream)에서 제공하는 기능이다.
- 메소드 체인이라고도 불린다.
- 시작 스트림 -> 중간 파이프 -> 최종 파이프
- 원리
배열 -> 스트림 -> 조작(A) -> 스트림 -> 조작(A) -> 스트림 -> 조작(B) -> ...반복
1. 시작, 중간조작(A): 중간처리 -> 필터링, 매핑, 정렬, 그룹핑 등...
2. 마지막 조작(B): 최종처리 -> 합계, 평균, 카운트, 최댓값, 최솟값, forEach 등...
[ 필터링 ]
- filter()
- 중간 처리 파이프
- 반환값으로 필터링이 된 Stream을 반환하기 때문에 계속 이어서 다른 파이프를 연결할 수 있다.
[ 예제1 - 필터링으로 짝수 구하기 ]
- 스트림 시작 -> filter 처리(중간 파이프) -> forEach 처리(최종 파이프)
- 스트림 시작 -> 홀수 걸러내기(짝수 찾기) -> 남은 숫자(짝수) 출력하기
// 수업상 편의를 위해 Data.getIntList(15)에 임의의 숫자가 15개 들어있습니다.
// [36, 12, 36, 86, 24, 1, 32, 65, 85, 86, 78, 16, 57, 7, 65]
List<Integer> list = Data.getIntList(15);
list.stream() // 스트림 시작
.filter(n -> n % 2 == 0) // 중간 파이프(filter)
.forEach(n -> System.out.printf("%4d" , n)); // 최종 파이프(forEach)
--> Output
36 12 36 86 24 32 86 78 16
[ 예제2 - 필터링으로 성별 구하기 ]
// 수업상 편의를 위해 Data.getUserList()에 임의의 정보가 들어가 있습니다.
// [name=하하하, age=25, weight=75, height=177, gender=2], [name=박명수, age=23, weight=82, height=183, gender=1]...
// gender가 1인 사람(남자)
Data.getUserList().stream()
.filter(user -> user.getGender() == 1)
.forEach(user -> System.out.println(user.getName()));
// gender가 2인 사람(여자)
Data.getUserList().stream()
.filter(user -> user.getGender() == 2)
.forEach(user -> System.out.println(user.getName()));
--> 남자 Output
홍길동
아무개
유재석
박명수
강호동
이수근
정형돈
--> 여자 Output
하하하
테스트
호호호
[ 중복 제거 ]
- distinct()
- 중간 처리 파이프
[ 예제 - 중복 제거 + 필터링 ]
- 배열에 들어있는 내용 중 중복된 문자를 제거하고, 3글자 이상만 불러오기
List<String> names = Arrays.asList("홍길동", "아무개", "하하하", "김훈", "김훈", "홍길동", "호호호", "아무개", "김길동", "테스트");
names.stream()
.distinct() // 중간 파이프(중복 제거)
.filter(name -> name.length() >= 3) // 중간 파이프(필터링)
.forEach(name -> System.out.println(name));
--> Output
홍길동
아무개
하하하
호호호
김길동
테스트
[ 매핑 ]
- mapXXX()
- 중간 처리 파이프
- 스트링 요소 -> 다른 형태의 요소(값)으로 변환해서 반환하는 작업
- 매핑은 데이터 가공(변환)할때 쓰인다.
- 매핑은 리턴값에 따라 자료형이 달라진다.
1) word -> word.lenth() : Integer
2) word -> word : String
3) word -> true : Boolean
[ 예제 - 나이를 구해서 세대(데이터 가공) 구하기 ]
// 수업 편의를 위해 Data.getIntList(10)에는 임의의 숫자 10개가 들어가 있습니다.
// [36, 12, 36, 86, 24, 1, 32, 65, 85, 86]
Data.getIntList(10).stream
.map(n -> (n / 10) * 10) // 원본데이터 -> 다른 성격의 데이터 가공
.forEach(n -> System.out.println("세대: " + n + "대"));
--> Output
세대: 30대
세대: 10대
세대: 30대
세대: 80대
세대: 20대
세대: 0대
세대: 30대
세대: 60대
세대: 80대
세대: 80대
[ 정렬 ]
- 배열, 컬렉션
- 스트림 정렬
- sorted()
- 중간 처리 파이프
- 요소를 정렬 후 정렬된 스트림을 반환한다.
[ 예제1 - 배열에 있는 숫자 정렬 ]
- sort vs sorted
// 수업상 편의를 위해 Data.getIntList(15)에 임의의 숫자 15개가 들어있습니다.
// [ 36 12 36 86 24 1 32 65 85 86 78 16 57 7 65 ]
// 방법1 - 기존 sort
List<Integer> list1 = Data.getIntList(15);
list1.sort((a, b) -> a - b); // 오름차순 정렬
ist1.stream().forEach(n -> System.out.printf("%4d", n));
// 방법2 - sorted
List<Integer> list2 = Data.getIntList(15);
list2.stream()
.sorted()
.forEach(n -> System.out.printf("%4d", n));
--> sort Output
1 7 12 16 24 32 36 36 57 65 65 78 85 86 86
--> sorted Output
1 7 12 16 24 32 36 36 57 65 65 78 85 86 86
[ 예제2 - 배열에 있는 숫자 역정렬 ]
List<Integer> list1 = Data.getIntList(15);
list4.stream()
.sorted((a, b) -> b - a)
.forEach(n -> System.out.printf("%4d", n));
--> Output
86 86 85 78 65 65 57 36 36 32 24 16 12 7 1
[ 집계 ]
- 통계값 함수
- 최종 처리 파이프
- count()
- 데이터 집합의 요소를 가공해서 축소하는 작업(Reduction)
[ 예제 - 필터 + 집계 함수 이용 ]
- 임의의 숫자 리스트에서 짝수, 홀수 개수 구하기
- 임의의 정보 리스트에서 남자, 여자 개수 구하기
// 임의의 숫자 리스트에서 짝수, 홀수 개수 구하기
System.out.println(Data.getIntList().stream().count()); // 총 개수
System.out.println(Data.getIntList().stream().filter(n -> n % 2 == 0).count()); // 짝수 개수
System.out.println(Data.getIntList().stream().filter(n -> n % 2 == 1).count()); // 홀수 개수
System.out.println();
// 임의의 정보 리스트에서 남자, 여자 개수 구하기
System.out.println(Data.getUserList().stream().count()); // 총 정보 수
System.out.println(Data.getUserList().stream().filter(user -> user.getGender() == 1).count()); // 총 남자 수
System.out.println(Data.getUserList().stream().filter(user -> user.getGender() == 2).count()); // 총 여자 수
--> 짝수, 홀수 Output
100
56
44
--> 남자, 여자 Output
10
7
3
[ 중간 파이프 이용 시 주의 사항 ]
- 오늘 배운 중간 파이프 filter, distinct, map, sort 등 여러가지가 있는데, 중간 파이프는 계속 이어서 붙여 나갈 수 있는 특징이 있다. 하지만 위치(순서)에 따라 값이 달라질 수도 있다.
1. distinct -> filter
2. filter -> distinct
위 두 방식의 결과는 달라질 수 있다!
[ 요약 정리 ]
중간파이프 | filter | 중간에 걸러내는 작업이며 즉, 조건을 줄 수 있다.( 여러개 붙여서 가능 ) |
distinct | 중복값 제거 | |
map | 데이터 가공할 때 쓰이며, 기존 스트링 요소를 다른 형태의 값으로 변환해서 반환해준다. | |
sorted | 정렬 | |
최종파이프 |
forEach | 배열에 있는 리스트를 하나씩 읽어 온다. (향상된 for문과 비슷) |
count | 집계 |
MEMO>
# 스트림 사용시 여러 파이프를 연결하다 보면 코드가 길어질 수 있는데, 그때마다 .stream 형식으로 끝나는 지점에 들여쓰기를 하기도한다. (회사마다 다름)
# 스트림 filter에서 조건을 줄 수 있는데, 하나의 filter에서 여러개의 조건을 주는것도 가능하지만, 가독성도 떨어지고 에러가 날수 있으므로 권장하는 방법은 filter를 여러개 쓰는것이다!! ---> 하나의 조건당 하나의 필터!
# 스트림 요소가 동작하는 흐름을 잘 파악해보자. 스트림 Start -> 중간 파이프 작업 -> 최종 파이프 작업..
# 중간 파이프는 계속 이어서 쓸 수 있지만, 순서에 따라 결과가 달라질 수도 있다는걸 명심하자.
'교육 > Java' 카테고리의 다른 글
Java 개발자 수업 93일차 - 팀 프로젝트로 인한 수업X (0) | 2021.08.07 |
---|---|
Java 개발자 수업 91일차 - 스트림(Stream) (0) | 2021.08.07 |
Java 개발자 수업 90일차 - Function, Operation, Predicate, 함수 조합용 메소드 (0) | 2021.08.07 |
Java 개발자 수업 89일차 - 함수형 인터페이스(Functional Interface), Consumer, Supplier (0) | 2021.08.07 |
Java 개발자 수업 88일차 - 람다식 (Lambda Expression) (0) | 2021.07.31 |
댓글