먼저 BufferedReader를 알기 전 Buffer에 대해 이해하는 것이 좋다고 생각했다.
컴퓨팅에서 버퍼(buffer, 문화어: 완충기억기)는 데이터를 한 곳에서 다른 한 곳으로 전송하는 동안 일시적으로 그 데이터를 보관하는 메모리의 영역이다. 버퍼링(buffering)이란 버퍼를 활용하는 방식 또는 버퍼를 채우는 동작을 말한다. 다른 말로 '큐(Queue)'라고도 표현한다.
버퍼는 컴퓨터 안의 프로세스 사이에서 데이터를 이동시킬 때 사용된다. 보통 데이터는 키보드와 같은 입력 장치로부터 받거나 프린터와 같은 출력 장치로 내보낼 때 버퍼 안에 저장된다. 이는 전자 통신의 버퍼와 비유할 수 있다. 버퍼는 하드웨어나 소프트웨어에 추가될 수 있지만 버퍼는 상당수가 소프트웨어에 추가된다. 버퍼는 보통 속도가 계속 바뀔 수 있으므로 데이터 수신, 처리 속도에 차이가 있다. (예: 프린터 스풀러)
버퍼는 네트워크 상에서 자료를 주고 받을 때나 스피커에 소리를 재생할 때, 또는 디스크 드라이브와 같은 하드웨어의 입출력을 결합하는 데에 자주 이용된다. 버퍼는 또한 순서대로 데이터를 출력하는 FIFO 방식에서 보통 사용된다.
BufferedReader는 아래와 같이 상속관계를 가진다.
java. lang.Object
java.io.Reader
java.io.BufferedReader
BufferedReader는 Reader를 확장
문자, 배열 및 줄을 효율적으로 읽을 수 있도록 문자 입력 스트림에서 텍스트를 읽음.
버퍼 크기를 지정하거나 기본 크기를 사용 가능.
일반적으로 Reader에 대한 읽기 요청은 기본 문자, 바이트 스트림에 대한 읽기 요청을 발생시킴, 즉 FileReader나 InputStreamReaders와 같이 읽기 작업에 비용이 많이 드는 Read를 BufferReader에 저장하는 것이 효율적임.
Char , Byte ), 방향( Input , Output ) 에 따라 결절됨. FileReader , InputStreamReaders 는 Char로 반환됨ex) BufferReader = new BufferReader(new FileReader("Foo.in"));
문자를 입력할 때 문자를 한 번에 메모리에 저장하여 전송시간이 줄어들어 성능이 향상될 수 있다. 그렇기에 버퍼리더를 쓰는 것이 문자를 입력받을 때 효율적일 것이다.
Scanner
BufferedReader
참고 이미지

즉 Scanner는 짧은 데이터를 저장하고 보내는 것에 있어서는 효율적일 수도 있겠지만, 많은 데이터를 보내려고 할 때에는 BufferedReader 를 쓰는 것이 더 효율적임.
BufferedReader bf = new BufferedReader(new InputStreamReader(System.in)); //선언
String s = bf.readLine(); //String, 입력
int i = Integer.parseInt(bf.readLine()); //Int 형변환
readLine으로 입력을 받지만, String으로 고정되기에 다른 값으로 받으려면 형변환이 필요함.throws IOException을 통해 예외처리를 해줘야함.// StringTokenizer
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
int N = Integer.parseInt(st.nextToken());
int M = Integer.parseInt(st.nextToken());
// String.split() 함수
String arr[] = s.split(" ");