[JAVA] BufferedReader/ BufferedWriter/ StringBuilder

2022. 6. 9. 18:43Programming의 세계/JAVA

일단 왜???

굳이 코드 복잡한 이런 아이들을 사용하는 이유 : 

1. 메모리 초과 문제

2. 속도 지연 문제

 

String은 불변객체이다. String에 대한 설명을 보면 String의 값은 생성하면 변경 불가하다는 것을 알 수 있다. 그럼 그동안 + 하면서 만들던 것은 다 뭐였지?????

 

		String greeting = "hello";
		System.out.println(greeting.hashCode());
		greeting = "hello" + "!!!!!";
		System.out.println(greeting.hashCode());
		greeting = "hello" + "oo";
		System.out.println(greeting.hashCode());

같은 변수 greeting이지만 이들이 다 다른 hashCode를 가지는 것을 확인 할 수 있다.

내부적으로 합친내용을 가진변수를 새로운 메모리에 추가 되는 것이다. 때문에 용량이 하나 더 는다고 생각해야지 String이 변한다고 생각하면 안된다.

 

 

바로 이런 점때문에 짧은 알고리즘의 경우는 차이가 없겠지만 데이터가 많아지거나 복잡해지면 이런 문제가 큰 걸림돌이 된다. BufferedReader와 StringBuilder을 사용하는 습관을 길들여야한다.

 

 


BufferedReader

 

BufferedReader클래스는 버퍼를 이용하는 대표적인 I/O(input/output) 클래스다.

입력된 데이터를 바로 전달하는 것이 아닌, 버퍼에 저장해두었다가 전달하는 방법이다.

Scanner 클래스와 다른 점은,

Scanner 클래스는 Space, Enter 모두 경계로 입력값을 인식하고, BufferedReader 클래스는 Enter만을 경계로 입력값을 인식한다. 이러한 차이 때문에 데이터 양이 많을 경우에는 한번에 모아서 전달하는 BufferedReader가 훨씬 빠르고 효율적이다.

 

 

BufferedReader 사용방법

1. BufferedReader를 사용을 위해 선언하면서 관련 패키지를 import 한다. (import 가져오기는 메모리를 차지하지 않는다.)

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

BufferedReader buffer = new BufferedReader(new InputStreamReader(System.in));

 

2. BufferedReader 사용법

1) 선언해준다.

BufferedReader buffer = newBufferedReader(new InputStreamReader(System.in));

 

2) 문자열 입력받기

String [] input = buffer.readLine();

readLine은 한 줄을 의미한다. 또한 항상 String 형태로 입력을 받는다. 

 

3)  정수로 형변환

//정수로 받거나
int number = Integer.parseInt(buffer.readLine());

//문자열로 받은뒤 정수화
String str = buffer.readLine();
int number = Integer.parseInt(str);

때문에 int값을 사용하기 위해서는 다음같이 형 변환을 해줘야 한다.

 

4) 공백으로 구분된 정수 입력받기

String [] input = buffer.readLine().split(" ");
int n1 = Integer.parseInt(input[0]);
int n2 = Integer.parseInt(input[1]);

 


BufferedWriter

 

bufferedWriter도 마찬가지로 많은 양의 출력에서 효율적이다.

//BufferedWriter 선언
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
String str = "Print str";

//출력
bw.writer(str);

//개행
bw.newLine();

//남아있는 데이터 모두 출력
bw.flush(); 

//스트림 닫기
bw.close();

 


StringBuilder

서두에 말했듯 + 연산자를 많이 사용하면 할 수록 그만큼 String 객체의 수가 늘어나기 때문에, 프로그램 성능을 느리게 하는 요인이 된다. 

StringBuilder도 StringBuffer와 마찬가지로 내부 버퍼에 문자열을 저장해 두고, 그 안에서 추가, 수정, 삭제 작업을 할 수 있도록 설계되어 있어 사용방법이 동일하다. 차이점은 멀티 스레드 환경에서 안전한지에 여부에 있는데, StringBuffer는 멀티스레드 환경에서 사용할 수 있도록 동기화가 적용되어 있어 스레드에서 안전하고 StringBuilder는 안전하지 않다.

 

1) 선언부분

StringBuilder sb = new StringBuilder(); //16개의 문자들을 저장할 수 있는 초기 버퍼 내장
StringBuilder sb2 = new StringBuilder(30);//30개의 초기 버퍼크기 설정
StringBuilder sb3 = new StringBuilder("java"); //문자열을 버퍼의 초기값을 설정

StringBuilder의 버퍼 크기는 부족할 경우 늘어나기 때문에 크기 설정은 그다지 중요하지 않다.

그래서 대부분 첫번째 선언방식을 쓴다.

 

2) builder에 쌓기

sb.append("abc");

append(...) : 문자열 끝에 주어진 매개 값을 추가

 

3) 줄바꿈 포함하여 builder에 쌓기

sb.append(1).append('/n');

 

4) 문자열 중간에 매개값을 추가

sb.inset(4,"2");

4번째에 "2"를 삽입.

 

5) 문자열 삭제

delete(2, 3);

문자열 2 번째 부터 3번째 전까지 삭제

 

6) 문자열 대치

sb.replace(2, 4, "!!!");

2번째부터 4번째전까지를 문자열 "!!!"으로 변경. 

 

7)문자열 순서 변경

sb.reverse();

abc -> cba 처럼 문자열 순서를 전복시킨다.

 

5) 쌓아둔 문장들 출력

System.out.println(sb);
System.out.println(sb.toString());

 


StringBuilder와 StringBuffer를 알아보는 과정에서 StringTokenizer이란 클래스가 많이 보였다. 

문자열을 불리할때 쓰는 클래스라는데 StringTokenizer도 알아가는 시간을 갖도록 해야겠다. 

 

 

D.O.N.E!!!