재귀 이해
메소드가 자기 자신을 호출하는 프로그래밍 기법으로, 다음 주의사항이 적용됩니다:
- 반드시 종료 조건(exit condition)이 존재해야 함
- 호출 깊이 제한으로 스택 오버플로우 방지
- 생성자에서는 재귀 사용 불가
기본 재귀 예제
public class RecursionExample {
public static void main(String[] args) {
recursiveMethod(3);
}
static void recursiveMethod(int count) {
System.out.println("진입: " + count);
if(count > 0) {
recursiveMethod(count - 1);
}
System.out.println("탈출: " + count);
}
}
재귀 활용 사례
1에서 N까지 합계 계산:
public class SumCalculator {
public static void main(String[] args) {
System.out.println(calculateSum(5)); // 15 출력
}
static int calculateSum(int num) {
return (num == 1) ? 1 : num + calculateSum(num - 1);
}
}
팩토리얼 계산:
public class Factorial {
public static void main(String[] args) {
System.out.println(computeFactorial(5)); // 120 출력
}
static int computeFactorial(int n) {
return (n <= 1) ? 1 : n * computeFactorial(n - 1);
}
}
피보나치 수열:
public class Fibonacci {
public static void main(String[] args) {
System.out.println(getFibonacci(7)); // 13 출력
}
static int getFibonacci(int pos) {
return (pos == 1 || pos == 2) ? 1
: getFibonacci(pos - 1) + getFibonacci(pos - 2);
}
}
디렉토리 탐색:
import java.io.File;
public class DirectoryTraverser {
public static void main(String[] args) {
traverse(new File("src"));
}
static void traverse(File dir) {
for(File item : dir.listFiles()) {
if(item.isDirectory()) {
traverse(item);
} else if(item.getName().endsWith(".java")) {
System.out.println(item.getAbsolutePath());
}
}
}
}
바이트 스트림 파일 처리
입출력 스트림은 데이터 전송을 위한 추상화된 개념으로, 다음과 같이 분류됩니다:
| 구분 | 입력 | 출력 |
|---|---|---|
| 바이트 스트림 | InputStream | OutputStream |
| 문자 스트림 | Reader | Writer |
파일 복사 구현
FileInputStream/FileOutputStream 활용:
import java.io.*;
public class FileCopier {
public static void main(String[] args) throws IOException {
try (
InputStream origin = new FileInputStream("source.txt");
OutputStream target = new FileOutputStream("target.txt")
) {
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = origin.read(buffer)) != -1) {
target.write(buffer, 0, bytesRead);
}
}
}
}
버퍼 스트림 성능 향상:
import java.io.*;
public class BufferedFileCopier {
public static void main(String[] args) throws IOException {
try (
BufferedInputStream in = new BufferedInputStream(
new FileInputStream("source.txt"));
BufferedOutputStream out = new BufferedOutputStream(
new FileOutputStream("target.txt"))
) {
byte[] dataChunk = new byte[4096];
int chunkSize;
while ((chunkSize = in.read(dataChunk)) != -1) {
out.write(dataChunk, 0, chunkSize);
}
}
}
}
성능 비교
| 방식 | 소요 시간 |
|---|---|
| 1바이트 단위 복사 | 188ms |
| 바이트 배열 복사 | 1ms |
| 버퍼 1바이트 복사 | 6ms |
| 버퍼 배열 복사 | 0ms |