
자바 코딩테스트를 준비할 때 Scanner 혹은 BufferReader를 통해 데이터를 입력 받습니다. 어떠한 원리로 자바에서 데이터를 입력받는지 한번 이해하고 알아보도록 하겠습니다.
Java에는 데이터를 입력받는 방법이 두 가지가 있습니다. Scanner 와 BufferedReader 2가지 입니다.
Scaaner란 입력 스트림에서 다양한 종류의 데이터를 읽을 수 있도록 도와주는 유틸리티 클래스입니다. primitive 타입과 문자열을 구문 분석할 수 있는 간단한 텍스트 스캐너입니다. 스캐너는 기본적으로 토큰 단위로 입력값의 경계를 인식하여 데이터를 입력받습니다.
⚠️ 토큰 단위 : 공백 문자(스페이스바, 엔터, 탭 등)으로 구분
Scanner sc = new Scanner(System.in);
Scanner sc = new Scanner(new File("myFile"));
Scanner 클래스를 사용하려면 먼저 해당 클래스의 객체를 생성해야합니다. 이때 System.in 을 전달하여 키보드 입력을 받거나, 파일을 입력받을 수 있습니다.
int i = sc.nextInt(); //정수 읽기
long l = sc.nextLong();
float f = sc.nextFloat();
double d = sc.nextDouble();
String s = sc.next(); //공백을 제외한 문자열 읽음
String fullLine = sc.nextLine();
Scanner 객체를 생성한 후에는 다양한 메서드를 사용하여 데이터를 읽을 수 있습니다. 데이터 타입이 입력받는 시점에서 결정되어 별도의 형변환이 필요하지 않아 쉽게 입력 받을 수 있습니다.
위의 코드에서 next() 메서드를 통해 문자열을 읽을 때, 공백 이전까지의 문자열만 읽습니다. 만약 공백을 포함한 문자열 전체를 읽고 싶다면 nextLine() 메서드를 사용할 수 있습Bu니다.
BufferedReader는 Java에서 데이터를 읽을 때 성능을 향상시키기 위해 사용되는 클래스 중 하나입니다. 특히, 파일이나 네트워크 소켓 등에서 한 줄씩 데이터를 효율적으로 읽을 때 많이 활용됩니다.
BufferedReader inputReader = new BufferedReader(new InputStreamReader(System.in));
BufferedReader fileReader = new BufferedReader(new FileReader("example.txt")
B**ufferedReader**는 Reader 클래스를 기반으로 하며, 생성자에 Reader 객체를 전달하여 생성합니다. FileReader, InputStreamReader 등을 사용하여 데이터 소스를 지정할 수 있습니다.
try (BufferedReader reader = new BufferedReader(new FileReader("example.txt"))) {
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
BufferedReader는 한 줄씩 데이터를 읽을 수 있는 readLine() 메서드를 제공합니다. 이 메서드는 다음 줄을 문자열로 반환하며, 파일의 끝에 도달하면 null을 반환합니다. 참고로 BufferedReader를 사용하여 데이터를 받을 때 는 예외처리를 필수로 처리해주어야 합니다.
BufferedReader 가 더 성능이 좋아 자주 사용되지만, Scanner와 다르게 토큰으로 잘라주지 않기 때문에 토큰 객체를 새로 생성해줘야 합니다. 이때 사용되는 것이 바로 StringTokenizer 입니다
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
위와 같이 파라메터로 BufferedReader를 StringTokenizer에 넣어주면, 해당 한 줄을 토큰 단위로 나누어줍니다. 토큰을 가져올 때는 nextToken() 메소드를 통해 토큰 단위로 나누어진 데이터를 가져옵니다. 이때 토큰 형식으로 나누어준 데이터 역시 String 타입입니다. 그렇기 때문에 int 와 같이 String이 아닌 다른 타입을 써주기 위해서는 Integer.parseInt() 와 같은 메소드를 통해 따로 형변환을 해줘야 합니다.
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
int n1 = Integer.parseInt(st.nextToken());
int n2 = Integer.parseInt(st.nextToken());
위와 같은 코드를 예시로, “123 456” 을 입력했다면 br 에는 “123 456” 그대로 한 줄이 담기고, st는 토큰으로 “123” “456” 이 담기고, n1과 n2에는 Integer.parseInt() 를 사용해 123 과 456 정수형으로 값이 저장이 되는 것입니다. 또한 주의해야할 점이 토큰 단위로 이미 나뉘어져있기 때문에, nextToken()이라는 메서드를 통해서 한 단어를 가져오는데 한번 가져온 토큰은 한 번 더 가져올 수 없으므로 변수로 따로 저장해놔야합니다.
| Scanner | BufferedReader | |
|---|---|---|
| 패키지 | java.util | java.io |
| 성능 | 상대적으로 낮음 | 상대적으로 빠름 |
| 입력 형식 처리 | 다양한 입력 형식에 대해 직접적인 지원을 제공합니다. 정수, 실수, 문자열 등을 각각의 메서드로 읽을 수 있음 | 기본적으로 문자열을 읽어오며, 문자열을 원하는 형식으로 파싱하려면 추가적인 처리가 필요 |
| 용도 | 사용자 입력 처리 또는 파일에서 다양한 데이터 타입을 읽을 때 사용 | 주로 텍스트 파일에서 텍스트 데이터를 읽을 때 사용 |
Scanner와 BufferedReader는 둘 다 입력 스트림에서 데이터를 읽기 위한 클래스입니다. 일반적으로 성능면에서 BufferedReader 가 더 빨라 속도를 빠르게 하기 위해 BufferedReader를 주로 사용하지만, 파싱을 해야하는 추가 작업이 필요하다는 단점이 있습니다. Scanner은 상대적으로 성능이 떨어지지만, 다양한 데이터 타입을 추가 파싱 작업없이 바로 입력받을 수 있어 편의성이 높다는 장점이 있습니다.