java stream에서 maptoobj 함수는 중간 연산이라 되어 있습니다. 길이 n짜리 배열을 obj object n개로 채우려고 합니다. obj 클래스에는 int 자료형만 하나 있고, 우리는 이 n개의 obj가 깊은 복사가 되어야 해요. 이걸 stream을 써서 할 때, Intstream의 range 메서드와, maptoObj를 사용하면 손쉽게 처리할 수 있습니다.
![](https://blog.kakaocdn.net/dn/btvvRB/btsezC5u4ZR/niZRc7x2ca5M771c8nSuG0/img.png)
mapToObj 메서드를 봅시다. Intstream 뿐만이 아니라, Longstream과 DoubleStream에도 있습니다. 설명을 보면, 스트림으로부터 해당 함수를 적용한 객체 값들의 stream을 반환한다고 되어 있어요. 즉 입력 스트림으로부터 무언가를 받아서, 새로운 결과 가지고 있는 스트림으로 변환합니다.
n개의 크기를 가진 리스트에 깊은 복사한 Obj 오브젝트 n개를 채워야 한다고 해 볼게요. 그러면 단순하게 List를 새로 생성해서 Obj 객체를 추가해도 됩니다. 그런데, 조금 더 생각해 보면 아래와 같은 로직을 생각할 수 있습니다.
![](https://blog.kakaocdn.net/dn/bgkfzb/btsex3Q37pB/XRlA1wReqQYk9qFXYmWVD0/img.png)
1부터 5까지 있는 stream이 있어요. 이것을 아래와 같이 변환시키면 어떨까요?
![](https://blog.kakaocdn.net/dn/bqGZnN/btseAdEAjT5/Zx7JE7r63BpmLeftkkKeT0/img.png)
하나의 원소가 새로운 new Obj(3)으로 바뀌는 것입니다. mapToXXX류가 이러한 역할을 수행합니다. 이 경우 IntStream의 원소들을 다른 obj로 변환시키는 apply 작업을 수행했습니다.
![](https://blog.kakaocdn.net/dn/msCRj/btsezEhWJNH/xlrM6y6Pz6koOcG7xk1TN0/img.png)
그림으로 그리면 이런 상황인 셈입니다. 즉, mapToXXX는 스트림의 요소들을 다른 요소로 바꾼 새로운 스트림을 돌려줍니다. 위 그림에서는 x를 new Obj(3)으로 바꾸었습니다. 따라서, 1 2 3 4 5로 이루어져 있던 것을 new Obj(3), ... , new Obj(3)으로 대체하게 됩니다.
이제 문제 상황을 다시 봅시다. 저는 객체 Obj n개가 채워진 ArrayList를 원합니다. 객체 n개는 깊은 복사가 되어야 하고요. 객체 Obj는 int 필드 하나만 주어져 있습니다. n = 4라고 해 보겠습니다.
![](https://blog.kakaocdn.net/dn/dUAlu8/btsezM1xGNO/lNwcMuL5lP7pEIyNGCO730/img.png)
당연하게도, setter가 있기 때문에, 불변 객체가 아닙니다. 어떻게 하면 될까요? 로직부터 설계해 봅시다. 일단, 이전에 배웠던 range는 1부터 n까지의 순서를 가지는 stream을 생성합니다. 고로, IntStream.range(1, 5)를 먼저 수행합니다.
![](https://blog.kakaocdn.net/dn/bioC3u/btsey42hjt4/C6IRt60jmwckezQF8P1Wzk/img.png)
다음에, 해당 stream을 토대로 Obj로 이루어진 스트림을 새로 생성합니다. mapToObj로요.
![](https://blog.kakaocdn.net/dn/qKyg7/btsey33mkzv/n5uAZCeyl2pE8EyhXNEAY1/img.png)
그러면, 1부터 5까지 순서로 이루어진 Stream이 new Obj(3)으로 이루어진 4개의 객체로 이루어 집니다. 참고로 각 원소별로 apply가 별개로 동작하므로 매번 새로운 객체가 생기게 됩니다.
![](https://blog.kakaocdn.net/dn/07Fjl/btseAT6T9OV/kc9LfcupnkqRLlCygCE9z1/img.png)
toList로 Stream을 List로 변환합니다.
![](https://blog.kakaocdn.net/dn/bjjl04/btseywSxSEC/wM6V1vCBo5wQFC6p86bw8K/img.png)
최종 코드는 20 ~ 21번째 줄에 나와 있습니다. 23번째 줄에 list의 0번째 원소의 x 값을 2로 바꾸어 봅시다. 만약에 저 객체들이 모두 얕은 복사가 되었다면, 모두 2가 출력되었을 겁니다.
![](https://blog.kakaocdn.net/dn/eCOM6m/btsezCEq0KT/PBTufxhDesgna2Z8rnLVM1/img.png)
그런데 3이 출력되었습니다. 이유는 toList가 호출될 때 mapToObj에 있는 apply인 x -> new Obj(3)가 실행되기 때문입니다. 각각의 element에 대해 적용되기 때문에 별개의 새로운 오브젝트 Obj가 생성됩니다.
출처: https://codingdog.tistory.com/entry/java-stream-maptoobj-함수에-대해-알아봅시다 [강아지의 코딩공부:티스토리]
'Java' 카테고리의 다른 글
MyBatisPagingItemReader with ExecutorType.Batch (0) | 2024.07.10 |
---|---|
[MyBatis] Page with MyBatis (0) | 2024.07.01 |
[Spring Security] Public vs Private method to be applied Spring Security (1) | 2024.06.07 |
[Spring Batch] multiple nodes with MySQL 8.0.33 (0) | 2024.05.03 |
자바 어플리케이션 inputstream 주의사항 (1) | 2024.04.18 |