길이가 같은 두 배열 a, b의 내적을 구하기.
a[0]b[0] + a[1]b[1] + ... + a[n-1]*b[n-1]
import java.util.stream.IntStream;
class Solution {
public int solution(int[] a, int[] b) {
int answer = 0;
answer = IntStream.range(0, a.length)
.map(idx -> a[idx] * b[idx])
.sum();
return answer;
}
}
동작은 했다. 근데 리팩토링 포인트가 있었다.
// 기존
int answer = 0;
answer = IntStream.range(...)...
// 개선
int answer = IntStream.range(...)...
0으로 초기화하고 바로 재할당하는 건 의미없는 코드. 선언과 동시에 할당하면 된다.
range vs rangeClosed헷갈리기 쉬운 부분.
| 메서드 | 범위 |
|---|---|
IntStream.range(0, n) | 0 ~ n-1 (끝 미포함) |
IntStream.rangeClosed(0, n) | 0 ~ n (끝 포함) |
배열 인덱스는 0부터 length-1까지라서 range(0, a.length)가 맞다.
"두 배열 길이가 같아서"가 이유가 아니라, 배열 인덱스 구조 때문이다.
reduce를 알게 됐다.map().sum() 쓴 게 틀린 건 아닌데, reduce가 뭔지 몰랐다.
reduce란?스트림의 여러 요소를 하나의 값으로 합치는 연산.
reduce(초기값, (누적값, 현재값) -> 누적값 + 현재값)
내적 문제에 적용하면:
IntStream.range(0, a.length)
.map(idx -> a[idx] * b[idx]) // 각 쌍을 곱해서 변환
.reduce(0, (acc, curr) -> acc + curr); // 누적 합산
실제 동작 흐름 (a = [1,2,3,4], b = [-3,-1,0,2]):
| 단계 | acc | curr | 결과 |
|---|---|---|---|
| 초기 | 0 | - | 0 |
| 1 | 0 | -3 | -3 |
| 2 | -3 | -2 | -5 |
| 3 | -5 | 0 | -5 |
| 4 | -5 | 8 | 3 |
acc : reduce(0, ...) 에서 0이 초기값이라서 0부터 시작curr : .map()이 변환한 값을 하나씩 꺼내서 전달sum()이 더 낫다reduce는 덧셈 외에 커스텀 누적 연산이 필요할 때 진가를 발휘한다.
단순 합산이면 .sum()이 의도를 더 명확하게 드러낸다.
map → 변환
reduce → 커스텀 누적
sum → 단순 합산 (가독성 최고)
이 문제는 안전하지만, 항상 확인하는 습관을 들여야 한다.
1,000 * 1,000 = 1,000,0001,000,000 * 1,000 = 10억int 최대: 약 21억 → 이 문제는 안전만약 배열 길이가 10,000이었다면? → long 필요.
제한사항 보고 overflow 가능성 먼저 확인하기.
import java.util.stream.IntStream;
class Solution {
public int solution(int[] a, int[] b) {
return IntStream.range(0, a.length)
.map(idx -> a[idx] * b[idx])
.sum();
}
}
range vs rangeClosed — 배열 인덱스 구조 때문에 range 선택map = 변환, reduce = 커스텀 누적, sum = 단순 합산reduce(초기값, (acc, curr) -> acc + curr) 구조 기억