코딩테스트 문제 풀다 보면 Scanner보다 BufferedReader / BufferedWriter을 더 많이 쓰게 된다.
버퍼를 사용하면 어떤 점이 더 좋을까?

버퍼를 사용하지 않는 입력은, 키보드의 입력이 키를 누르는 즉시 바로 프로그램에 전달
반면 버퍼를 사용하는 입력은, 키보드의 입력이 있을 때마다 한 문자씩 버퍼로 전송한다.
버퍼가 가득 차거나 개행 문자가 나타나면 버퍼의 내용을 한 번에 프로그램에 전달
즉, 입력 데이터를 한 번에 모아서 전달
Scanner는 데이터를 토큰 단위로 처리하고 띄어쓰기와 개행문자를 경계로 하여 입력 값을 인식
그렇기 때문에 따로 가공할 필요가 없어 편리하다.
BufferedReader은 입력 받은 데이터가 String으로 고정되기 때문에 입력받은 데이터를 원하는 타입으로 가공하는 작업이 필요함.
- Scanner는 기본형 데이터 타입(정수, 실수 등)을 입력받을 때 편리 (입력이 단순하고 분할이 필요한 경우)
- BufferedReader는 대량의 텍스트 입력을 처리하거나, 라인 단위로 데이터를 읽을 때 적합,속도가 중요한 경우에 권장
- 백준 알고리즘 2741번 문제를 Scanner와 BufferedReader로 코딩시 Scanner(696ms) / BufferedReader(192ms)
- Buffer에서 readLine()을 쓰면 한 줄 단위로 데이터를 읽기 때문에 공백 단위로 데이터를 읽기 위해서는 StringTokenizer 객체나
String의 split 메서드를 사용해야 함
Scanner와 Buffer 속도 차이를 비교 하고 싶으면 아래 코드를 사용해서 테스트 ㄱㄱ
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Scanner;
public class InputSpeedTest {
public static void main(String[] args) throws IOException {
// 테스트 횟수 설정
int numIterations = 100000;
// Scanner로 입력 테스트
long startTime = System.nanoTime();
Scanner scanner = new Scanner(System.in);
for (int i = 0; i < numIterations; i++) {
int number = Integer.parseInt(scanner.nextLine());
}
scanner.close();
long endTime = System.nanoTime();
System.out.println("Scanner time: " + (endTime - startTime) + " ns");
// BufferedReader로 입력 테스트
startTime = System.nanoTime();
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
for (int i = 0; i < numIterations; i++) {
int number = Integer.parseInt(reader.readLine());
}
reader.close();
endTime = System.nanoTime();
System.out.println("BufferedReader time: " +
(endTime - startTime) + " ns");
}
}
- BufferedReader 사용법
BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); // 선언
String s = br.readLine();
int i = Integer.parseInt(br.readLine());
br.close()
선언한 후 입력은 readLine();이라는 메서드로 한다.
먼저, 입력타입변환이 필요하다. BufferedReader는 readLine()메서드를 통해 문자열(String)만 반환하기 때문에 숫자 등 다른 데이터 타입으로 사용하려면 직접 형변환해야 함. 예를 들어, 정수를 읽으려면 Interger.parseInt(br.readLine()) 같은 방식으로 문자열을 정수로 변환해 주어야 함.
그리고, 예외처리를 반드시 필요로 한다. BufferedReader의 메서드들은 IOException을 발생시킬 수 있음. 그래서 readLine()시 마다 try/catch 블록으로 감싸주어도 되고, main 메서드에 throws IOException(일반적) 을 추가하여 예외 처리를 해 주어도 된다.
마지막으로 입력 종료시 자원 해제를 해 주어야 한다. close() 메서드 호출해 주는데 보통 br.close()를 한다. 이는 메모리 누수를 방지하는데 도움이 된다. ㅎㅎ
- 데이터 가공 할 때 쓰는 StringTokenizer, split()
BufferedReader를 통해 읽어온 데이터는 개행문자 단위(Line 단위)로 나누어진다.
만약 이를 공백 단위로 데이터를 가공하고자 하면 따로 작업을 해주어야 한다.
이때 사용하는 것이 StringTokenizer나 String.split() 함수이다.
StringTokenizer는 구분자를 기준으로 문자열을 토큰화해주며, split()은 정규 표현식을 사용해 문자열을 분리한다.
StringTokenizer의 nextToken() 함수를 쓰면 readLine()을 통해 입력 받은 값을 공백 단위로 구분하여 순서대로 호출할 수 있다.
String.split() 함수를 사용하면, 배열에 공백단위로 끊어 데이터를 저장하여 사용할 수 있다.
이렇게만 말하면 무슨 뜻인지 이해하기 힘드니까 코드를 보자.
BufferedReader를 사용하여 사용자로부터 한 줄로 된 "Hello World Java"를 입력받고, 공백을 기준으로 나누어 각 단어를 출력하는 프로그램을 만들어 보자.
1. 입력 받기:
BufferedReader를 통해 사용자로부터 문자열을 입력받음
예를 들어, 사용자가 "Hello World Java"를 입력하면 이 문자열이 input 변수에 저장됨
2. 공백으로 문자열 분리:
StringTokenizer 또는 String.split(" ") 메서드를 사용하여 입력된 문자열을 공백을 기준으로 나누고,
각 단어를 토큰이나 배열로 만들기
3. 단어 출력:나누어진 각 단어를 반복문을 통해 출력
"Hello", "World", "Java" 출력됨
StringTokenizer 사용한 코드
공백을 기본 구분자로 사용하여 입력된 문자열을 단어 단위로 나눔
hasMoreTokens() 메서드를 사용해 더 이상 토큰이 없을 때까지 출력 반복
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
import java.util.StringTokenizer;
public class Example {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String input = br.readLine(); // 예: "Hello World Java"
StringTokenizer st = new StringTokenizer(input); // 기본 구분자: 공백
while (st.hasMoreTokens()) {
String word = st.nextToken();
System.out.println(word);
}
br.close();
}
}
String.split() 사용한 코드
split(" ") 메서드는 입력된 문자열을 공백을 기준으로 나누어 배열 형태로 반환.
이 배열을 통해 각 단어에 접근
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
public class Example {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String input = br.readLine(); // 예: "Hello World Java"
String[] words = input.split(" "); // 공백을 기준으로 문자열 분리
for (String word : words) {
System.out.println(word);
}
br.close();
}
}
- BufferedReader을 써서 백준2751번 문제를 풀어 보자

import java.io.InputStreamReader;
import java.io.BufferedReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringBuilder sb = new StringBuilder();
int N = Integer.parseInt(br.readLine());
ArrayList<Integer> list = new ArrayList<>();
for(int i = 0; i < N; i++) {
list.add(Integer.parseInt(br.readLine()));
}
Collections.sort(list);
for(int value : list) {
sb.append(value).append('\n');
}
System.out.println(sb);
}
}
BufferedReader를 사용해 표준 입력으로부터 데이터를 읽고,
StringBuilder를 이용해 출력 형식을 조합한 뒤 최종적으로 정렬된 데이터를 출력하는 방식
1. BufferedReader 객체 생성:
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedReader는 InputStreamReader(System.in)을 감싸고 있어 콘솔 입력을 빠르게 읽을 수 있도록 함.
readLine() 메서드를 통해 한 줄씩 문자열 형태로 데이터를 읽어옴.
2. StringBuilder 객체 생성:
StringBuilder sb = new StringBuilder();
StringBuilder는 출력할 내용을 하나의 문자열로 조합하는 데 사용
반복해서 문자열을 연결할 때 + 연산자 대신 사용하여 성능을 높임
3. 데이터 입력 받기:
int N = Integer.parseInt(br.readLine());
4. ArrayList에 데이터 저장:
ArrayList<Integer> list = new ArrayList<>();
for(int i = 0; i < N; i++) {
list.add(Integer.parseInt(br.readLine()));
}
입력받은 N 개의 정수를 ArrayList<Integer>에 저장
각 입력 줄을 읽어온 후 Integer.parseInt()로 정수형으로 변환한 값을 list에 추가
5. 정렬 & 값 출력
Collections.sort(list);
for(int value : list) {
sb.append(value).append('\n');
}
System.out.println(sb);
for-each문을 사용해 list의 각 값을 StringBuilder 객체에 추가
마지막에는 System.out.println(sb);을 통해 모든 결과를 한 번에 출력
- BufferedWriter
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out)); // 선언
String str = "abcdef"; // 출력할 문자열
bw.write(s); // 출력
bw.newLine(); // 줄바꿈
bw.flush(); // 남아있는 데이터 모두 출력
bw.close();
일반적으로 출력을 할 때, System.out.println(""); 을 사용한다. 하지만 많은 양의 출력을 할 때는, 입력과 동일하게 버퍼를 사용하는 것이 좋다. BufferedWriter는 데이터를 한 번에 메모리에 저장하고, 버퍼가 가득 찼을 때나 flush()가 호출될 때 출력 장치(예: 파일)에 기록한다. 이로 인해 I/O 작업의 횟수를 줄여 성능을 개선한다. 특히 대량의 데이터를 출력할 때 이점이 크다.
이 때 개행처리를 해 줘야 하는데
newLine() 또는 write("\n") 을 사용한다. BufferedWriter는 System.out.println()과 달리 자동으로 개행을 처리하지 않는다. 따라서 각 출력 후에 개행을 추가하려면 newLine() 메서드 또는 write("\n")을 사용해줘야 한다. 여러 줄의 데이터를 출력할 때는 각 줄의 끝에 newLine()을 추가해야 한다.
그리고 모든 과정이 끝난 후에는 버퍼 비우기와 스트림 종료를 해 주어야 한다.
flush(): 버퍼에 남아 있는 데이터를 즉시 출력 스트림으로 보내는 메서드임. 여러 번 출력을 해야 할 경우 flush()를 사용하여 버퍼의 내용을 출력할 수 있음. close()는 출력 스트림을 완전 종료하는 메서드로 한 번 닫으면 다시 BufferedWriter 객체를 생성해 줘야 함.
- String Builder
StringBuilder sb = new StringBuilder();
sb.append("a");
sb.append("b").append(" ");
sb.append("c").append("\n");
'Java' 카테고리의 다른 글
[Java] ArrayList, 제네릭스(Generics), 정렬, Join, String.join 정리 (8) | 2024.11.03 |
---|---|
StringBuffer 사용법, 예시, String 과 차이, StringBuilder (5) | 2024.11.03 |
[Java] 자바8 Stream으로 List를 map으로 변환하기 (1) | 2024.10.27 |
찾아보다가 답답해서 내가 작성한 아주 쉽게 이해하는 서블릿의 개념과 작동원리! (+그림 포함) (0) | 2024.04.24 |
(자바) 접근제한자, 필드와 메서드 (0) | 2024.04.21 |
코딩테스트 문제 풀다 보면 Scanner보다 BufferedReader / BufferedWriter을 더 많이 쓰게 된다.
버퍼를 사용하면 어떤 점이 더 좋을까?

버퍼를 사용하지 않는 입력은, 키보드의 입력이 키를 누르는 즉시 바로 프로그램에 전달
반면 버퍼를 사용하는 입력은, 키보드의 입력이 있을 때마다 한 문자씩 버퍼로 전송한다.
버퍼가 가득 차거나 개행 문자가 나타나면 버퍼의 내용을 한 번에 프로그램에 전달
즉, 입력 데이터를 한 번에 모아서 전달
Scanner는 데이터를 토큰 단위로 처리하고 띄어쓰기와 개행문자를 경계로 하여 입력 값을 인식
그렇기 때문에 따로 가공할 필요가 없어 편리하다.
BufferedReader은 입력 받은 데이터가 String으로 고정되기 때문에 입력받은 데이터를 원하는 타입으로 가공하는 작업이 필요함.
- Scanner는 기본형 데이터 타입(정수, 실수 등)을 입력받을 때 편리 (입력이 단순하고 분할이 필요한 경우)
- BufferedReader는 대량의 텍스트 입력을 처리하거나, 라인 단위로 데이터를 읽을 때 적합,속도가 중요한 경우에 권장
- 백준 알고리즘 2741번 문제를 Scanner와 BufferedReader로 코딩시 Scanner(696ms) / BufferedReader(192ms)
- Buffer에서 readLine()을 쓰면 한 줄 단위로 데이터를 읽기 때문에 공백 단위로 데이터를 읽기 위해서는 StringTokenizer 객체나
String의 split 메서드를 사용해야 함
Scanner와 Buffer 속도 차이를 비교 하고 싶으면 아래 코드를 사용해서 테스트 ㄱㄱ
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.util.Scanner; public class InputSpeedTest { public static void main(String[] args) throws IOException { // 테스트 횟수 설정 int numIterations = 100000; // Scanner로 입력 테스트 long startTime = System.nanoTime(); Scanner scanner = new Scanner(System.in); for (int i = 0; i < numIterations; i++) { int number = Integer.parseInt(scanner.nextLine()); } scanner.close(); long endTime = System.nanoTime(); System.out.println("Scanner time: " + (endTime - startTime) + " ns"); // BufferedReader로 입력 테스트 startTime = System.nanoTime(); BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); for (int i = 0; i < numIterations; i++) { int number = Integer.parseInt(reader.readLine()); } reader.close(); endTime = System.nanoTime(); System.out.println("BufferedReader time: " + (endTime - startTime) + " ns"); } }
- BufferedReader 사용법
BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); // 선언 String s = br.readLine(); int i = Integer.parseInt(br.readLine()); br.close()
선언한 후 입력은 readLine();이라는 메서드로 한다.
먼저, 입력타입변환이 필요하다. BufferedReader는 readLine()메서드를 통해 문자열(String)만 반환하기 때문에 숫자 등 다른 데이터 타입으로 사용하려면 직접 형변환해야 함. 예를 들어, 정수를 읽으려면 Interger.parseInt(br.readLine()) 같은 방식으로 문자열을 정수로 변환해 주어야 함.
그리고, 예외처리를 반드시 필요로 한다. BufferedReader의 메서드들은 IOException을 발생시킬 수 있음. 그래서 readLine()시 마다 try/catch 블록으로 감싸주어도 되고, main 메서드에 throws IOException(일반적) 을 추가하여 예외 처리를 해 주어도 된다.
마지막으로 입력 종료시 자원 해제를 해 주어야 한다. close() 메서드 호출해 주는데 보통 br.close()를 한다. 이는 메모리 누수를 방지하는데 도움이 된다. ㅎㅎ
- 데이터 가공 할 때 쓰는 StringTokenizer, split()
BufferedReader를 통해 읽어온 데이터는 개행문자 단위(Line 단위)로 나누어진다.
만약 이를 공백 단위로 데이터를 가공하고자 하면 따로 작업을 해주어야 한다.
이때 사용하는 것이 StringTokenizer나 String.split() 함수이다.
StringTokenizer는 구분자를 기준으로 문자열을 토큰화해주며, split()은 정규 표현식을 사용해 문자열을 분리한다.
StringTokenizer의 nextToken() 함수를 쓰면 readLine()을 통해 입력 받은 값을 공백 단위로 구분하여 순서대로 호출할 수 있다.
String.split() 함수를 사용하면, 배열에 공백단위로 끊어 데이터를 저장하여 사용할 수 있다.
이렇게만 말하면 무슨 뜻인지 이해하기 힘드니까 코드를 보자.
BufferedReader를 사용하여 사용자로부터 한 줄로 된 "Hello World Java"를 입력받고, 공백을 기준으로 나누어 각 단어를 출력하는 프로그램을 만들어 보자.
1. 입력 받기:
BufferedReader를 통해 사용자로부터 문자열을 입력받음
예를 들어, 사용자가 "Hello World Java"를 입력하면 이 문자열이 input 변수에 저장됨
2. 공백으로 문자열 분리:
StringTokenizer 또는 String.split(" ") 메서드를 사용하여 입력된 문자열을 공백을 기준으로 나누고,
각 단어를 토큰이나 배열로 만들기
3. 단어 출력:나누어진 각 단어를 반복문을 통해 출력
"Hello", "World", "Java" 출력됨
StringTokenizer 사용한 코드
공백을 기본 구분자로 사용하여 입력된 문자열을 단어 단위로 나눔
hasMoreTokens() 메서드를 사용해 더 이상 토큰이 없을 때까지 출력 반복
import java.io.BufferedReader; import java.io.InputStreamReader; import java.io.IOException; import java.util.StringTokenizer; public class Example { public static void main(String[] args) throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); String input = br.readLine(); // 예: "Hello World Java" StringTokenizer st = new StringTokenizer(input); // 기본 구분자: 공백 while (st.hasMoreTokens()) { String word = st.nextToken(); System.out.println(word); } br.close(); } }
String.split() 사용한 코드
split(" ") 메서드는 입력된 문자열을 공백을 기준으로 나누어 배열 형태로 반환.
이 배열을 통해 각 단어에 접근
import java.io.BufferedReader; import java.io.InputStreamReader; import java.io.IOException; public class Example { public static void main(String[] args) throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); String input = br.readLine(); // 예: "Hello World Java" String[] words = input.split(" "); // 공백을 기준으로 문자열 분리 for (String word : words) { System.out.println(word); } br.close(); } }
- BufferedReader을 써서 백준2751번 문제를 풀어 보자

import java.io.InputStreamReader; import java.io.BufferedReader; import java.io.IOException; import java.util.ArrayList; import java.util.Collections; public class Main { public static void main(String[] args) throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); StringBuilder sb = new StringBuilder(); int N = Integer.parseInt(br.readLine()); ArrayList<Integer> list = new ArrayList<>(); for(int i = 0; i < N; i++) { list.add(Integer.parseInt(br.readLine())); } Collections.sort(list); for(int value : list) { sb.append(value).append('\n'); } System.out.println(sb); } }
BufferedReader를 사용해 표준 입력으로부터 데이터를 읽고,
StringBuilder를 이용해 출력 형식을 조합한 뒤 최종적으로 정렬된 데이터를 출력하는 방식
1. BufferedReader 객체 생성:
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedReader는 InputStreamReader(System.in)을 감싸고 있어 콘솔 입력을 빠르게 읽을 수 있도록 함.
readLine() 메서드를 통해 한 줄씩 문자열 형태로 데이터를 읽어옴.
2. StringBuilder 객체 생성:
StringBuilder sb = new StringBuilder();
StringBuilder는 출력할 내용을 하나의 문자열로 조합하는 데 사용
반복해서 문자열을 연결할 때 + 연산자 대신 사용하여 성능을 높임
3. 데이터 입력 받기:
int N = Integer.parseInt(br.readLine());
4. ArrayList에 데이터 저장:
ArrayList<Integer> list = new ArrayList<>(); for(int i = 0; i < N; i++) { list.add(Integer.parseInt(br.readLine())); }
입력받은 N 개의 정수를 ArrayList<Integer>에 저장
각 입력 줄을 읽어온 후 Integer.parseInt()로 정수형으로 변환한 값을 list에 추가
5. 정렬 & 값 출력
Collections.sort(list);
for(int value : list) { sb.append(value).append('\n'); } System.out.println(sb);
for-each문을 사용해 list의 각 값을 StringBuilder 객체에 추가
마지막에는 System.out.println(sb);을 통해 모든 결과를 한 번에 출력
- BufferedWriter
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out)); // 선언 String str = "abcdef"; // 출력할 문자열 bw.write(s); // 출력 bw.newLine(); // 줄바꿈 bw.flush(); // 남아있는 데이터 모두 출력 bw.close();
일반적으로 출력을 할 때, System.out.println(""); 을 사용한다. 하지만 많은 양의 출력을 할 때는, 입력과 동일하게 버퍼를 사용하는 것이 좋다. BufferedWriter는 데이터를 한 번에 메모리에 저장하고, 버퍼가 가득 찼을 때나 flush()가 호출될 때 출력 장치(예: 파일)에 기록한다. 이로 인해 I/O 작업의 횟수를 줄여 성능을 개선한다. 특히 대량의 데이터를 출력할 때 이점이 크다.
이 때 개행처리를 해 줘야 하는데
newLine() 또는 write("\n") 을 사용한다. BufferedWriter는 System.out.println()과 달리 자동으로 개행을 처리하지 않는다. 따라서 각 출력 후에 개행을 추가하려면 newLine() 메서드 또는 write("\n")을 사용해줘야 한다. 여러 줄의 데이터를 출력할 때는 각 줄의 끝에 newLine()을 추가해야 한다.
그리고 모든 과정이 끝난 후에는 버퍼 비우기와 스트림 종료를 해 주어야 한다.
flush(): 버퍼에 남아 있는 데이터를 즉시 출력 스트림으로 보내는 메서드임. 여러 번 출력을 해야 할 경우 flush()를 사용하여 버퍼의 내용을 출력할 수 있음. close()는 출력 스트림을 완전 종료하는 메서드로 한 번 닫으면 다시 BufferedWriter 객체를 생성해 줘야 함.
- String Builder
StringBuilder sb = new StringBuilder(); sb.append("a"); sb.append("b").append(" "); sb.append("c").append("\n");
'Java' 카테고리의 다른 글
[Java] ArrayList, 제네릭스(Generics), 정렬, Join, String.join 정리 (8) | 2024.11.03 |
---|---|
StringBuffer 사용법, 예시, String 과 차이, StringBuilder (5) | 2024.11.03 |
[Java] 자바8 Stream으로 List를 map으로 변환하기 (1) | 2024.10.27 |
찾아보다가 답답해서 내가 작성한 아주 쉽게 이해하는 서블릿의 개념과 작동원리! (+그림 포함) (0) | 2024.04.24 |
(자바) 접근제한자, 필드와 메서드 (0) | 2024.04.21 |