BufferedReader / BufferedWriter
BufferedReader와 BufferdWriter는 버퍼를 사용하여 읽기와 쓰기를 하는 함수이다.
버퍼를 사용하지 않는 입력은, 키보드의 입력이 키를 누르는 즉시 바로 프로그램에 전달된다.
반면 버퍼를 사용하는 입력은, 키보드의 입력이 있을 때마다 한 문자씩 버퍼로 전송한다. 버퍼가 가득 차거나 혹은 개행 문자가 나타나면 버퍼의 내용을 한 번에 프로그램에 전달한다.
한번 버퍼를 거쳐 출력되는 것보다, 키보드의 입력을 받는 즉시 출력하는 것이 더 빠른 것이 아닌가 생각할수 있다.
하드디스크는 속도가 느리다. 그리고 외부 장치(키보드, 모니터 등)와 데이터 입출력도 생각보다 시간이 오래 걸린다. 그렇기 때문에 키보드의 입력이 있을 때마다 바로 이동시키는 것 보다는, 중간에 버퍼를 두어 한번에 묶어 보내는 것이 더 효율적이고 빠른 방법이다.
쓰레기통을 비우는 일이라고 생각하면 이해가 쉽다. 쓰레기가 생길 때마다 하나하나 밖에 내다버리는 것보다, 집의 쓰레기통에 하나하나 모았다가, 꽉 차면 한번에 밖에 버리는게 훨씬 효율적인 것과 비슷한 개념이라고 생각하면 된다,
BufferedReader
Scanner와 달리 BufferedReader는 개행문자만 경계로 인식하고 입력받은 데이터가 String으로 고정된다. 그렇기 때문에 따로 데이터를 가공해야하는 경우가 많다. 하지만 Scanner보다 속도가 빠르다!
BufferedRead와 Scanner의 속도 차이를 잘 보여주는 예시가 있어 가져와 보았다.
10,000,000개의 0~1023 범위의 정수를 한 줄씩 읽고, 입력으로 받은 정수의 합을 출력하는 프로그램을 각각 BufferedReader와 Scanner로 구현할 때의 수행시간이다. [1]
입력 방식 | 수행시간(초) |
java.util.Scanner | 6.068 |
java.io.BufferedReader | 0.934 |
그리고 버퍼 사이즈도 Scanner가 1024 char인데 비해, BufferedReader는 8192 char(16,384byte) 이기 때문에 입력이 많을 때 BufferedReader가 유리하다.
또한 BufferedReader는 동기화 되기 때문에 멀티 쓰레드 환경에서 안전하고, Scanner는 동기화가 되지 않기 때문에 멀티 쓰레드 환경에서 안전하지 않다. (멀티 쓰레드에 대한 설명은 생략한다.)
- BufferedReader 사용법
입력은 readLine();이라는 메소드를 사용한다. String으로 리턴 값이 고정되어 있기 때문에, 다른 타입으로 입력을 받고자 한다면 반드시 형변환이 필요하다. 그리고, 예외처리를 반드시 필요로 한다. readLine()시 마다 try/catch문으로 감싸주어도 되고, throws IOException 을 통한 예외처리를 해도 된다.(대부분의 경우에 후자를 사용한다.)
- 데이터 가공
BufferedReader를 통해 읽어온 데이터는 개행문자 단위(Line 단위)로 나누어진다. 만약 이를 공백 단위로 데이터를 가공하고자 하면 따로 작업을 해주어야 한다. 이때 사용하는 것이 StringTokenizer나 String.split() 함수이다.
StringTokenizer의 nextToken() 함수를 쓰면 readLine()을 통해 입력 받은 값을 공백 단위로 구분하여 순서대로 호출할 수 있다.
String.split() 함수를 사용하면, 배열에 공백단위로 끊어 데이터를 저장하여 사용할 수 있다.
[백준] 전주 듣고 노래 맞히기풀이
import java.util.*;
import java.io.*;
public class Main {
public void solution() throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
StringTokenizer st = new StringTokenizer(br.readLine());
int n = Integer.parseInt(st.nextToken()), m = Integer.parseInt(st.nextToken());
HashMap<String, String> map = new HashMap<>();
while(n-- > 0) {
String[] arr = br.readLine().split(" ", 3);
String code = arr[2].substring(0, 5);
map.put(code, map.containsKey(code) ? "?\n" : arr[1] + "\n");
}
StringBuilder sb = new StringBuilder();
while(m-- > 0) {
sb.append(map.getOrDefault(br.readLine(), "!\n"));
}
bw.write(sb.toString());
bw.flush();
bw.close();
br.close();
}
public static void main(String args[]) throws Exception {
new Main().solution();
}
}
'Study > 코딩스터디_TIL' 카테고리의 다른 글
[JAVA 스터디] Map getOrDefault 사용법 (0) | 2025.01.25 |
---|---|
[JAVA 스터디] 250122 Map 객체 활용 (1) | 2025.01.22 |
[JAVA 스터디] 250121 해시 알고리즘 (0) | 2025.01.21 |
[JAVA 스터디] 250120 hash 함수 (1) | 2025.01.20 |
[JAVA 스터디] 250116 BufferedReader (1) | 2025.01.16 |