[Java] 편해도 Scanner 이제 그만..

김호준·2021년 10월 28일
0
post-custom-banner

버퍼(Buffer) 란 ?

  • 처리속도가 빠른 장치와 느린 장치 사이의 속도차이를 개선하여 효율을 개선하게 해주는 중간 장치라고 생각할 수 있다.
    • Ex) 입출력에서의 Buffer
      • CPU와 보조기억장치 사이의 속도차이를 개선하여 준다.
      • 즉, 데이터를 처리하는 CPU는 속도가 빠르지만 데이터를 가지고 있는 보조기억장치는 느리다. 따라서 Buffer에 보조기억장치에서 처리가 필요한 데이터를 저장해놓고 CPU가 Buffer를 통으로 처리한다고 생각하면 편할 것이다.
      • 먼저 처리요청된 데이터를 처리해야 하므로 선입선출(FIFO)구조가 필요하다. 그렇기 때문에 Queue를 이용해서 구현된다.

1. BufferedReader 와 BufferedWriter

  • 사실 Scanner 이외의 입출력 방식을 사용해본적이 없다. 하지만 백준 알고리즘 문제를 풀다가 Scanner를 사용했을 때는 시간이 초과되어 BufferedReader를 사용해야만 하는 문제가 있어 해당 함수를 알게 되었고 보다 효율적이고 빠른 방법이라는 것도 알게되었다.

Scanner

  • Scanner은 띄어쓰기와 개행문자를 경계로 하여 입력값을 인식한다. 그렇기 때문에 따로 가공할 필요가 없어 편리하다. 가공할 필요가 없다는 뜻은 입력받을 데이터의 타입을 정의해 입력받을 수 있어 다시 타입을 재정의해주어야 하는 가공 프로세스가 필요 없다.
  • Scanner의 Buffer Size는 1024 char이다.

BufferedReader

  • BufferedReader는 개행문자만 경계로 인식하고 입력받은 데이터는 String 타입으로 고정되기 때문에 따로 데이터를 가공해야하는 경우가 많다. 하지만 Scanner의 속도보다 빠르다.

  • BufferedReader의 Buffer Size는 8192 char 이기 때문에 입력이 많을수록 Buffer가 유리하다.

  • BufferedReader 사용

BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String a = br.readLine();
int i = Integer.parseInt(br.readLine());
  • BufferedReader를 이용하여 받은 데이터 가공
// 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(" ");

BufferedWriter

  • 일반적으로 출력은 System.out.print("")를 사용하였었지만, 많은 양의 출력에서는 마찬가지로 BufferedWriter가 유리하다.
  • BufferedWriter는 println과 다르게 출력과 동시에 개행을 동시에 해주지 않기 때문에 \n 이나 따로 newLine();을 사용해 주어야 한다.
  • 또한 버퍼를 잡아놓았기 때문에 사용 이후에 .flush() / .close()를 해주어야 한다.
  • BufferedWriter 사용
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
String str = "가나다"     // 출력할 문자열

bw.write(str);   // 출력
bw.newLine();    // 줄바꿈
bw.flush();	 // 남아있는 데이터 모두 출력
bw.close();
int i = Integer.parseInt(br.readLine());

StringBuilder

  • String과 StringBuilder / StringBuffer의 차이
    • String은 불변 속성을 갖고 StringBuilder / StringBuffer 은 그렇지 않다는 것이다.

      • String이 불변성을 갖는다는 것은 concat이나 + 연산을 통해 값을 변경하면, 기존 String 메모리에서 바뀌는 것이 아니라 기존 String에 있던 값을 해제하고 새로운 값을 재할당하게 된다. 처음에 할당한 String의 메모리 영역은 Garbage로 남아있다가 GarbageCollection에 의해 사라진다.
      • 불변성의 특징 때문에 변하지 않는 값을 자주 읽어들이는 경우 사용하면 유리하다. 하지만 추가, 삭제, 수정 등의 연산이 자주일어나는 경우에는 힙 메모리에 많은 Garbage가 생성되기 때문에 성능이 악화될 수 있다.
    • 이를 해결하기 위해 StringBuilder / StringBuffer 가 등장했다.

      • StringBuilder / StringBuffer는 가변성을 가지기 때문에 .append(), .delete()등 동일 객체 내에서 문자열을 변경하는 것이 가능하다. 그렇기 때문에 문자열의 추가, 수정, 삭제 등의 연산이 자주 발생할 경우 사용해야 한다.
    • StringBuilder / StringBuffer 둘의 차이점

      • StringBuffer : 동기화를 지원하여 멀티 쓰레드 환경에서 안전하다.

      • StringBuilder : 동기화를 지원하지 않아 멀티 쓰레드 환경에 사용하기 적합하지 않다. 대신, 동기화를 지원하지 않기에 단일쓰레드에서는 StringBuffer보다 성능이 뛰어나다.

      • StringBuilder 사용법

            StringBuilder sb = new StringBuilder();
	    sb.append("a");
	    sb.append("b").append(" ");
	    sb.append("c").append("\n");	
profile
Go-getter Developer
post-custom-banner

0개의 댓글