출처: https://dlee0129.tistory.com/238#recentComments
정리!
1. 왜 Scanner가 아닌 BufferedReader를 사용해야 하는가? 입력속도가 더 빠르다!
Scanner가 키보드 입력즉시 바로바로 프로그램에 전달되지만 BufferedReader는 버퍼가 다 채워지거나 개행 문자가 나타날 때까지 받아들인 후 프로그램에 전달됨.
2. 자바 응용 프로그램은 입력 장치로부터 직접 데이터를 읽지 않고 입력 스트림을 통해 데이터를 읽는다.
3. 그 외 BufferedReader사용시 BufferedReader br= new BufferedReader(new InputStreamReader(System.in));과 같이 형식이 복잡한지를 알수 있는내용.
자바를 처음 배울 때 사용자(키보드) 입력받기 위해 보통 Scanner 클래스를 사용합니다. 하지만 알고리즘을 풀기 시작하면서 백준에서 Scanner를 사용하여 입력을 받으면 시간초과가 발생하는 경험을 하게 됩니다. 그래서 다른 방법을 찾다 보면 BufferedReader를 접하게 됩니다.
Scanner와 BufferedReader 클래스는 둘 다 사용자(키보드) 입력을 받을 수 있는 기능을 제공합니다. 두 클래스가 가지고 있는 함수들에도 많은 차이가 있지만 가장 큰 차이는 속도입니다.
Scanner와 BufferedReader의 사용법
import java.util.Scanner;
public class Input {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String input = sc.nextLine();
}
}
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class Input {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String input = br.readLine();
}
}
백준님이 작성하신 입력 속도 비교 글을 보면 평균적으로 BufferedReader 사용시에 0.6585, Scanner 사용시에 4.8448 초가 걸리는 차이가 있습니다. 적은 양의 데이터인 경우 문제가 없겠지만, 데이터 양이 많아질수록 성능 차이는 큽니다.
https://www.acmicpc.net/blog/search/%EC%9E%85%EB%A0%A5+%EC%86%8D%EB%8F%84
BufferedReader를 사용할때와 Scanner의 속도가 차이가 나는 이유는 buffer 사용 여부의 차이입니다.
Scanner는 1KB 크기의 버퍼를 갖기 때문에 입력이 바로 전달되는 반면 BufferedReader는 8KB 크기의 버퍼를 가져 buffer에 입력들을 저장하였다 한 번에 전송하기 때문에 속도가 더 빠릅니다.
또한, Scanner는 입력을 읽는 과정에서 내부에서 정규 표현식 적용, 입력값 분할, 파싱 과정 등을 거치기 때문에 속도가 느립니다.
두 클래스가 공통적으로 생성할때에 System.in을 매개변수로 받는 것을 볼 수 있습니다.
System.in은 java.lang 패키지의 System 클래스이며, System클래스의 in은 정적(static) 변수입니다.
public final class System {
public static final InputStream in = null;
...
}
in은 InputStream 타입의 변수임을 볼 수 있습니다.
InputStream은 java.io 패키지의 바이트 단위 입력을 위한 최상위 입력 스트림 클래스입니다.
System.in을 매개변수로 사용하기 때문에 사용자(키보드) 입력을 받을 수 있다고 생각하시면 됩니다.
다음과 같이 System.in만을 사용하여 입력을 받는 것이 가능합니다.
import java.io.IOException;
public class Input {
public static void main(String[] args) throws IOException {
int input = System.in.read();
}
}
System.in과 BufferedReader 클래스를 사용할 때는 main 옆에 throws IOException이 붙습니다.
사용자의 입력은 여러 다양한 타입으로 들어올 수 있는데, 잘못된 값이 들어올 경우 에러가 나지 않도록 예외처리를 해줘야합니다.
Scanner는 System.in을 생성시에 내부에서 try-catch를 사용하여 예외처리를 하기때문에 예외처리를 하지 않아도 됩니다.
위의 코드를 보면 Scanner와 달리 BufferedReader는 생성시에 매개변수로 InputStreamReader를 사용합니다.
Scanner 또한 클래스 생성자에서 InputStreamReader를 생성하여 사용합니다.
public final class System {
public Scanner(InputStream source) {
this(new InputStreamReader(source), WHITESPACE_PATTERN);
}
...
}
따라서 다음과 같이 InputStreamReader를 생성하여 매개변수로 전달하는것도 가능합니다.
import java.io.InputStreamReader;
import java.util.Scanner;
public class Input {
public static void main(String[] args) {
Scanner sc = new Scanner(new InputStreamReader(System.in));
String input = sc.nextLine();
}
}
InputStreamReader란 문자 입력 스트림의 한 종류로 입력 장치(키보드 등)으로 부터 받은 입력 값을 자바 응용 프로그램으로 전달하는 객체입니다. 자바 응용 프로그램은 입력 장치로부터 직접 데이터를 읽지 않고 입력 스트림을 통해 데이터를 읽습니다.
스트림에 대해 자세히 알고 싶으시면 아래 포스트를 참조해주세요.
'자바 언어 & 객체지향 지식' 카테고리의 다른 글
자바 Reflection(리플랙션)에 대해서 (0) | 2023.10.09 |
---|---|
Subtyping VS Subclassing (0) | 2023.10.06 |
자바 익숙히 할 표현법들(스트림 라이브러리, 그래프표현법 등등) (0) | 2023.09.26 |
자바 스트림 라이브러리에 대하여 (0) | 2023.09.14 |
var에 대하여 (0) | 2023.09.14 |