Java에서는 사용자에게 입력받기 위해 두가지 클래스를 사용할 수 있다.
바로 Scanner와 BufferedReader !
Scannerjava.util.Scanner 클래스
1KB 크기의 버퍼를 가짐
➜ 키보드를 누르는 즉시 입력이 바로 전달
입력을 읽는 과정에서 내부에서 정규 표현식 적용, 입력값 분할, 파싱 과정 등을 거침
➜ 속도가 느림
직관적이고 사용이 편리
띄어쓰기와 개행문자를 기준으로 입력값을 인식하여 데이터를 따로 가공할 필요 X
입력값의 경계로 공백, 엔터 모두 인식 가능
동기화되지 않음
➜ 여러 스레드에서 동시에 사용할 경우 문제
BufferedReaderJava.io.BufferedReader 클래스
8KB 크기의 버퍼를 가짐
➜ buffer에 입력들을 저장해놨다가 버퍼가 가득차거나 개행 문자가 나타났을 때 한번에 전송
➜ 속도가 더 빠름
개행문자만 기준으로 입력값을 인식하고, 입력된 데이터의 형식이 String으로 고정되어 데이터의 가공 필요
➜ 공백도 문자열로 인식하기 때문에 StringTokenizer 사용 필요
입력과 동시에 동기화
클레스 레벨에서 throws IOException 해야함
💬 입력받은 즉시 전송하는 Scanner가 더 효율적인 것 아닐까?
➜ 버퍼링없이 전송하는 것은 CPU와의 성능 차이 때문에 버퍼를 사용하는 방식보다 속도에서 비효율적이라고 할 수 있음!
⠀
Ex. 과일을 수확할 때,
과일을 하나 딸 때마다 바로 창고로 옮기는 것과 /
수확한 과일을 수레에 한번에 모아 창고로 옮기는 것의 차이 !
👉 적은 양의 데이터가 오갈땐 큰 차이가 없을 수 있지만, 데이터의 양이 많아질수록 성능 차이가 큼 !
그러니까 BufferedReader를 사용하자 ~
import java.util.Scanner; ... Scanner scan = new Scanner(System.in); String str = scan.nextLine(); int a = scan.nextInt();
nextLine()- 개행을 기준으로 한 줄을 읽음next()- 공백을 기준으로 한 단어를 읽음
import java.io.BufferedReader; import java.io.InputStreamReader; import java.io.IOException; ... public static void main(String[] args) throws IOException { BufferReader br = new BufferedReader(new InputStreamReader(System.in)); ⠀ String str = br.readLine(); // 키보드로 입력받은 것 int a = Integer.parseInt(br.readLine()); // 키보드로 입력받은 것 int b = Integer.parseInt(str); // 키보드로 입력받은 str 문자열을 int로 변환한 것 }
💡 왜 BufferdReader를 사용할 때만 main 옆에 throws IOException이 붙을까?
➜ 사용자의 입력은 다양한 타입으로 들어올 수 있기 때문에 항상 예외처리를 해주어야 하는데,
Scanner는 System.in 생성 시에 내부에서 try-catch를 사용하여 예외처리를 하기 때문에 필요가 없고,
BufferedReader는 내부에서 예외처리를 할 수 없어서throws IOException으로 예외처리를 해주는 것 !