반응형
해당 글에서는 Java에서 사용목적에 따라 반복문에 대해 이해를 돕기 위해 작성한 글입니다
0) 반복문 요약
💡 반복문은 중점은 속도보다는 각각의 목적에 따라서 사용되기에 각각의 목적에 맞게 사용하는 것이 중요합니다.
💡 그리고 또한 컴퓨터의 하드웨어, 소프트웨어 등에 따라서 속도차이가 발생할 수 있기에 각각의 속도 차이를 확인할 수 없습니다.
분류 | 반복문 종류 | 사용 목적 |
내부 메서드 | for | 배열/컬렉션의 ‘인덱스’ 기반 처리가 필요한 경우 사용 |
내부 메서드 | for-each | 배열/컬렉션에서 인덱스가 필요하지 않고 ‘데이터 요소만’ 처리해야 하는 경우 사용 |
내부 메서드 | Iterator | 컬렉션 순회 중 ‘데이터 구조에 변경(삭제)’이 생기는 경우 사용 |
내부 메서드 | while | 특정 조건이 충족될 때까지 반복 실행해야 하는 경우 사용 (*반복 실행 전 조건을 검사) |
내부 메서드 | do-while | 특정 조건이 충족될 때까지 반복 실행해야 하는 경우 사용 (*반복 실행 후 조건을 검사) |
Stream 메서드 | Arrays.stream().forEach() | 배열/컬렉션을 순회하며 ‘주어진 동작만을 수행’하며 스트림 자체를 변경하지 않는데 사용 |
Stream 메서드 | Arrays.stream().map() | 각 요소에 대해 특정 작업을 수행하고 결과를 ‘새로운 스트림으로 반환’하는데 사용 |
Stream 메서드 | Arrays.stream().filter() | 배열/컬렉션에서 특정 조건을 ‘만족하는 요소만 필터링’하는 데 사용 |
Stream 메서드 | Arrays.stream().forEachOrdered() | 스트림의 각 요소에 대해 지정된 작업을 수행하면서 ‘요소의 순서’를 보장하는 데 사용 |
Stream 메서드 | Arrays.stream().flatMap() | ‘중첩된 컬렉션 또는 맵’을 처리하는 데 유용한 도구로 복잡한 처리 작업을 간소화하는 데 사용 |
Stream 메서드 | Arrays.stream().reduce() | 배열/컬렉션의 모든 요소를 ‘하나의 값으로 축소’하는 데 사용 |
[ 더 알아보기 ]
💡 내부 메서드를 사용하지 않고 Stream 메서드를 사용하는 이유는 무엇인가?
1. 배열을 스트림으로 변환하면 배열의 모든 요소에 대해 스트림 메서드를 사용할 수 있는데, 이는 배열을 다룰 때 발생하는 번거로운 작업을 간소화하고 코드의 가독성과 유지보수성을 높일 수 있다는 장점이 있습니다.
2. 모든 요소를 반복하며 수행하는 작업, 각 요소를 변환하는 작업, 조건에 맞는 요소만을 추출하는 작업에 대해 연속적으로 사용하여 복잡한 작업을 구현하는데 유용합니다.
1) 내부 메서드
1. for 문
💡 for 문
- 배열이나 컬렉션에서 조건이 ‘참’인 경우 반복되는 루프이며 해당 반복문은 ‘인덱스’를 기반으로 ‘데이터 구조’에 접근을 하는 반복문입니다.
- for문은 일반적으로 배열, 리스트 또는 범위를 반복하는 데 사용됩니다.
💡 [구조]
1. 초기화 식은 변수를 초기화하는 데 사용됩니다.
2. 조건식은 반복이 계속되는지 여부를 결정합니다.
3. 증감식은 반복이 실행될 때마다 변수를 업데이트합니다.
// for문 구문
for (초기화 식; 조건식; 증감식) {
// 반복 실행될 코드
}
💡 [ 예시 ]
- 0에서 9까지의 숫자를 출력하려면 다음과 같이 for문을 사용할 수 있습니다.
- 변수 i를 0으로 초기화하고, i가 10보다 작은 경우에만 반복되며, 반복이 실행될 때마다 i가 1씩 증가합니다. 따라서 위의 코드는 0에서 9까지의 숫자를 출력합니다.
for (int i = 0; i < 10; i++) {
System.out.println(i);
}
2. for-each 문
💡 for-each문
- 배열이나 컬렉션에서 모든 요소에 대해 반복하는 데 사용되는 루프이며 해당 반복문은 ‘데이터 요소에 직접 접근’을 하는 반복문입니다.
- for-each문은 일반적으로 for 루프보다 간단하고 가독성이 좋습니다.
💡 [구조]
1. type은 컬렉션에서 반복할 데이터 요소의 유형입니다.
2. variableName은 현재 반복되는 요소의 이름입니다.
3. collection: 반복할 컬렉션입니다.
for (type variableName : collection) {
// 실행 코드
}
💡 [예시]
- names 배열의 모든 요소를 출력합니다. 각 요소는 name 변수에 할당되며, for-each 루프가 반복될 때마다 현재 요소가 출력됩니다.
for (String name : names) {
System.out.println(name);
}
3. for문 for-each문의 속도 차이 : 비교
💡 for문은 배열과 같은 데이터 구조에 대한 ‘인덱스’를 사용하여 접근하기 때문에 인덱스를 통해 메모리 상에서의 ‘위치를 찾아가며 데이터를 참조’합니다. 이러한 접근 방식은 배열의 크기가 큰 경우 메모리 접근 시간에 큰 영향을 미치므로 성능이 높습니다.
💡 for-each문은 인덱스를 사용하지 않고 ‘데이터의 요소(element)에 직접 접근’하여 처리합니다. 이렇게 되면 데이터의 위치 정보를 찾아가는 시간이 없기 때문에 for문보다 성능이 떨어집니다.
분류 | for문 | for-each문 |
사용 가능 범위 | 배열, 컬렉션 등 | 배열, Iterable 객체 등 |
사용 목적 | 모든 종류의 반복 작업 | 컬렉션 등에서 데이터를 반복적으로 처리 |
코드 가독성 | 낮음 | 높음 |
성능 | 높음 | 낮음 |
인덱스 사용 여부 | 사용 | 미 사용 |
4. Iterator
💡 Iterator
- Collection의 요소를 순회하는 데 사용되는 인터페이스입니다.
- Iterator는 Collection의 모든 구현체에서 사용할 수 있으며, ‘요소를 안전하게 삭제’할 수 있는 방법을 제공합니다.
💡 [ 주요 메서드 ]
메서드 | 설명 |
boolean hasNext() | Iterator가 다음 요소를 가지고 있는지 확인합니다. |
E next() | Iterator가 가리키는 다음 요소를 반환합니다. |
void remove() | Iterator가 마지막으로 반환한 요소를 삭제합니다. |
💡 [ 사용 예시 ]
ArrayList<String> fruits = new ArrayList<String>();
fruits.add("apple");
fruits.add("banana");
fruits.add("orange");
Iterator<String> it = fruits.iterator();
while(it.hasNext()) {
String fruit = it.next();
System.out.println(fruit);
}
while(it.hasNext()) {
String fruit = it.next();
if(fruit.equals("banana")) {
it.remove();
}
}
System.out.println(fruits); // ["apple", "orange"]
5. while문
💡 while문
- 특정 조건이 충족(조건식이 참인 경우)될 때까지 코드 블록을 실행하는 제어문입니다.
- while문은 초기 조건식을 검사하고 조건식이 참(True)이면 코드 블록을 실행하고 다시 조건식을 검사하고, 조건식이 참(True)이면 코드 블록을 실행하는 과정을 반복합니다.
- 조건식이 거짓(False)이 되면 while문에서 빠져나와 다음 코드를 실행합니다.
💡 [구조]
1. 조건식 : 참(true) 또는 거짓(false)으로 평가되는 식(expression)을 의미합니다.
2. 실행 코드 : 반복적으로 실행될 코드의 집합을 의미합니다.
while (조건식) {
// 실행 코드
}
💡 [예시]
- 0부터 9까지의 정수를 출력하고 싶을 때는 다음과 같이 while문을 사용할 수 있습니다.
int i = 0;
while(i < 10) {
System.out.println(i);
i++;
}
6. do-while문
💡 do-while문
- 특정 조건이 충족(조건식이 참인 경우)될 때까지 코드 블록을 실행하는 제어문입니다.
- 특정 조건이 참(true)일 때 코드 블록을 실행하고, 조건식이 거짓(false)이 될 때까지 코드 블록을 반복적으로 실행하는 제어문입니다.
- while문과 다른 점은 do-while문은 루프의 끝에서 조건식을 검사한다는 것입니다.
💡 [구조]
1. 코드 블록은 최소한 한 번 실행되며, 그 후에 조건식이 검사됩니다.
2. 조건식이 참(true) 일 경우 코드 블록이 다시 실행되고, 이 과정은 조건식이 거짓(false)이 될 때까지 계속됩니다.
do {
코드 블록
} while (조건식);
💡 [예시]
- 0부터 9까지의 정수를 출력하기 위해 do-while문을 사용할 수 있습니다.
int i = 0;
do {
System.out.println(i);
i++;
} while (i < 10);
7) Stream 메서드
1. Arrays.stream().forEach()
💡 forEach()
- 스트림의 모든 요소에 대해 ‘주어진 동작’을 수행합니다.
- 이 메서드는 ‘void’를 반환하며, 스트림의 각 요소에 대해 주어진 동작을 수행합니다.
💡 [사용예시]
- 배열의 모든 요소를 콘솔에 출력하기 위한 예시입니다.
int[] arr = {1, 2, 3, 4, 5};
Arrays.stream(arr).forEach(System.out::println);
2. Arrays.stream().map()
💡 map()
- 스트림의 각 요소를 ‘새로운 값’으로 변환합니다.
- 이 메서드는 새로운 스트림을 반환하며, 변환된 값으로 이루어진 새로운 스트림을 생성합니다.
💡 [예시]
- 아래 코드는 배열의 각 요소를 제곱한 값으로 이루어진 새로운 스트림을 생성합니다.
int[] arr = {1, 2, 3, 4, 5};
Arrays.stream(arr).map(x -> x * x).forEach(System.out::println);
3. Arrays.stream().filter()
💡 filter()
- 메서드는 주어진 조건에 따라 스트림의 ‘요소를 필터링’합니다.
- 이 메소드는 새로운 스트림을 반환하며, 조건을 만족하는 요소로 이루어진 새로운 스트림을 생성합니다.
💡 [예시]
- 아래 코드는 배열에서 3보다 큰 요소로 이루어진 새로운 스트림을 생성합니다.
int[] arr = {1, 2, 3, 4, 5};
Arrays.stream(arr).filter(x -> x > 3).forEach(System.out::println);
4. Arrays.stream().forEachOrdered()
💡 forEachOrdered()
- forEach()와 유사하지만, 순서가 보장됩니다.
- 이 메서드는 void를 반환하며, 스트림의 각 요소에 대해 주어진 동작을 순서대로 수행합니다.
💡 [예시]
- 아래 코드는 배열의 모든 요소를 순서대로 출력합니다.
int[] arr = {1, 2, 3, 4, 5};
Arrays.stream(arr).forEachOrdered(System.out::println);
5. Arrays.stream().flatMap()
💡 flatMap()
- 스트림의 각 요소를 새로운 스트림으로 변환하고, 이를 하나의 스트림으로 '병합'합니다.
- 이 메서드는 새로운 스트림을 반환하며, 변환된 스트림들이 병합된 새로운 스트림을 생성합니다.
💡 [예시]
- 아래 코드는 2차원 배열을 1차원 배열로 변환합니다.
int[][] arr = {{1, 2}, {3, 4}, {5, 6}};
Arrays.stream(arr).flatMapToInt(x -> Arrays.stream(x)).forEach(System.out::println);
6. Arrays.stream().reduce()
💡 reduce()
- 스트림의 모든 요소를 하나의 값으로 줄입니다. 이 메서드는 Optional 값을 반환합니다.
💡 [예시]
- 아래 코드는 배열의 모든 요소의 합을 반환합니다.
int[] arr = {1, 2, 3, 4, 5};
int sum = Arrays.stream(arr).reduce(0, (x, y) -> x + y);
System.out.println(sum);
오늘도 감사합니다. 😀
반응형
'Java > 이론 및 문법' 카테고리의 다른 글
[Java] JVM(Java Virtual Machine) 이해하기 -1 : 동작 과정 (0) | 2023.10.06 |
---|---|
[Java] 반복문의 제어문(Control Flow Statement) 이해하기 (0) | 2023.10.03 |
[Java] 다양한 형 변환(Type Conversion) 방법 이해하기 : 캐스팅(Casting) (0) | 2023.08.26 |
[Java] JDK(Java Development Kit), Open JDK 이해하기 (0) | 2023.06.25 |
[Java] UUID 이해 및 사용방법 (0) | 2023.03.09 |