코딩테스트를 풀어가면서 다른 사람들의 풀이를 보다가 나는 for문으로 풀고 다른 사람들은 stream의 forEach문으로 문제를 풀어내는 것을 보고 for문과 forEach의 차이가 궁금해져 알아보게 되었습니다.
for문이 forEach문보다 먼저 개발되었다는 것은 모두가 아는 사실입니다. 그렇다면 for문이 코드를 작성하는데 큰 문제가 없는데 forEach문이 나오게 된 배경을 살펴봅시다.
그렇다면 for문으로도 문제없이 코드를 작성할 수 있는데, 왜 굳이 forEach가 등장하게 되었을까요?
모든 기능 개발의 원천에는 개발자들의 귀차니즘이 존재합니다.
forEach문도 마찬가지입니다. for문으로 여러 줄을 작성하던 것을 더 간단하고 읽기 쉽게 만든 것이 forEach문입니다.
for문은 아래와 같이 코드가 어쩔 수 없이 길어집니다.
// 배열의 합의 제곱이 배열 요소들의 곱보다 크다면, 1 반환, 아니면 0 반환
class Solution {
public int solution(int[] num_list) {
int mul = 1;
int sum = 0;
for (int i = 0; i < num_list.length; i++) {
sum += num_list[i];
mul *= num_list[i];
}
return sum * sum > mul ? 1 : 0;
}
}
// 향상된 for문
class Solution {
public int solution(int[] num_list) {
int mul = 1;
int sum = 0;
for (int i : num_list) {
sum += i;
mul *= i;
}
return sum * sum > mul ? 1 : 0;
}
}
🌟 tip) 향상된 for문을 사용하게 되면 인덱스를 사용하지 않아도 되기에 IndexOutOfBoundsException이 발생하지 않아 코드의 안정성이 올라갑니다.
향상된 for문을 활용하면 코드가 조금은 깔끔해진 느낌이 든다. 그러나 이것보다 간략히 코드를 작성할 수 있다면?
Stream을 활용하면 향상된 for문보다 더 짧은 코드를 제공합니다.
class Solution {
public int solution(int[] num_list) {
int mul = 1;
int sum = 0;
sum = Arrays.stream(num_list).sum();
mul = Arrays.stream(num_list).reduce(1, (i, j) -> i * j);
return sum * sum > mul ? 1 : 0;
}
}
위의 코드와 같이 코드의 길이가 많이 줄어듭니다. 따라서 가독성이 향상됩니다! stream API는 Java 8부터 도입된 기능으로, 데이터를 함수형 스타일로 처리할 수 있게 도와줍니다. 내부적으로 반복문을 추상화한 것이며, 일반적으로 for문보단 약간 느리지만, 차이는 대부분의 경우 미미하며 코드의 간결성과 함수형 스타일이 장점으로 언급됩니다.
break, continue를 사용하기 까다롭다는 점이 있고, stream을 사용하면 경우에 따라 map/filter 등으로 복잡해지는 경우 오히려 가독성을 해칠 수 있습니다.그렇다면 stream이 좋은가? for문이 좋은가? 이 문제는 상황에 따라 다릅니다. stream을 사용한다고 해서 항상 가독성이 뛰어난 것도 아니고, 항상 for문을 사용하기에는 귀찮음이 동반될 수 있습니다.
따라서 반드시 for문 혹은 stream을 사용하는 것이 아닌 상황에 맞게 올바른 문법을 채택하는게 권장됩니다.
➡️ 가독성, 성능, 제어 흐름의 유연성 등을 고려
💡 개발에서 중요한 건 “지금 이 문법이 이 상황에 가장 적절한가?"를 판단하는 것!
이미지 출처 : Baeldung 블로그
참고 출처 : 랸나 [JAVA] For과 Stream은 어떤 차이가 있는걸까?