코딩 기록들
[Java Stream Programming] 6. Mapping 본문
Mapping의 역할 : 형태를 바꿔줌
맵핑이란?
- 필터링이 SQL의 WHERE과 같다면, 맵핑은 SELECT컬럼과 같음
(단, 하나의 요소만 맵핑할수있음. 맵 내부에서 또다른 스트림을 만들면 안됨)
- 원본스트림의 내용을 변환하고자 할 때 사용
- 스트림의 원하는 요소만 추출해 새로운 스트림으로 생성함
(필터 : 걸러내는것, 매핑 : 원하는 요소를 뽑아내서 새로운 스트림을 만들겠다)
ex) 단어 4개가 들어있는 리스트를 이용해, 각 글자들의 길이를 갖는 숫자리스트를 만듦
List<String> words = Arrays.asList("Java8", "Lambdas", "In", "Action");
List<Integer> wordLengths = words.stream() //Stream() = Stream의 제네릭인 String
.map(String::length) // Map : String을 받아서 int를 반환함
.collect(Collectors.toList());
flatMap
- 맵과 동일하게 형태를 변환시킴
- Log 분석시 많이 사용 (Log : Application 동작에 대한 흔적)
- map을 통해 스트림 내부에서 도다른 스트림을 받고싶을때 사용
- 여러개의 파일을 읽을 때 사용
- 하지만, 잘 안씀
List<String> uniqueCharacters =
words.stream()
// 각 단어를 개별문자를 포함하는 배열로 변환
.map(w -> w.split("")) //String배열을 가지는 Stream이 생성됨
// 생성된 스트림을 하나의 스트림으로 평명화
.flatMap(Arrays::stream)
.distinct()
.collect(Collectors.toList());
flatMap 예제 ( flatMap : Stream.map내부에서 새로운 Stream을 반환할때 사용)
public class FlatMapExample {
public static void main(String[] args) {
//word.txt파일 읽어서 List로 변환하기
File file = new File("C:\\Java Exam", "word.txt");
List<String> wordList = null;
try {
wordList = Files.readAllLines(file.toPath(), Charset.forName("UTF-8"));
} catch (IOException e) {
e.printStackTrace();
}
// System.out.println(wordList);
// for (String line : wordList) {
// String[] letterArray = line.split(""); //비어있는 ""로 split -> 글자 하나하나단위로 자름
// for(String letter : letterArray) {
// System.out.println(letter);
// }
// }
//
String joinedLetter = wordList.stream() //Stream<String> : 한줄한줄 들어있는 스트림이 만들어짐
// peek : 스트림의 데이터가 어떻게 흘러가는지 보여줌(디버그용)
.peek(line -> System.out.println("line: " + line))
.map( line -> line.split("") ) //라인을 한글자한글자 자른것Stream<String[]>
// .peek(letterArray -> { //forEach()에는 바로윗줄의 string[]베열이 넘어옴
// System.out.println("Array: " + letterArray);
// for(String letter : letterArray) {
// System.out.println("Letter: " + letter);
// }
// })
/* map내부에서 stream 반환시키는 중일때
* flatMap을 사용하게되면
반환된 Stream이 원본 Stream을 대체함 */
.flatMap(letterArray -> Arrays.stream(letterArray)) //이렇게하면 스트림에 스트림을 또 넣게 되는 꼴
.peek(letter -> System.out.println("Peek: " + letter))
.distinct() //중복제거
// map이 stream을 반환시킬때, flatMap을 쓰면 간단하게 작성할수 있다
// .forEach(letter -> System.out.println("> " + letter));
.collect(Collectors.joining()); //한글자씩 떨어진 글자들을 하나의 스트링으로 모아준다
System.out.println(joinedLetter);
}
}
Map vs flatMap
- Stream 에서 반환되는 결과가 stream이 아니라면 : Map사용
- 반환결과가 stream일 경우, 차이가 발생함
-- map : 맵핑된 결과를 Stream 컬렉션에 넣어 반환 → Stream<Stream<Object>>
-- flatMap : 맵핑된 결과를 Stream으로 반환 → Stream<Object>