1. Scanner
- 띄어쓰기와 개행문자를 경계로 하여 입력 값을 인식한다.
- 원하는 타입의 입력을 받을 수 있기 때문에 따로 가공할 필요가 없다.
- 버퍼 사이즈가 1024 char이기 때문에 많은 입력을 필요로 하는 경우에는 좋지 못한 성능을 보인다.
- 동기화가 되지 않기 때문에 멀티스레드 환경에서 안전하지 않다.
2. BufferedReader
- 개행문자만 경계로 인식한다.
- readLine() 메서드로 입력 받는다.
- 입력 받은 데이터는 String으로 고정된다. 그렇기 때문에 따로 데이터를 가공해야 하는 경우가 많다.
- Scanner보다 속도가 빠르다.
- 버퍼 사이즈가 8192 char(16384 byte)이기 때문에 입력이 많을 때 유리하다.
- 동기화 되기 때문에 멀티스레드 환경에서 안전하다.
- 예외처리를 반드시 해야 한다. readLine() 마다 try/catch문으로 감싸주거나 throws IOException을 통해 처리한다.
//선언
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
//입력1
String s = br.readLine();
//입력2 : 형 변환
int i = Integer.parseInt(br.readLine());
2.1 데이터 가공
- BufferedReader를 통해 읽어온 데이터는 개행문자 단위로 나눠지기 때문에, 공백 단위로 가공하기 위해서는 추가적인 작업이 필요하다. 이 때 사용하는 것이 StringTokenizer와 String.split() 함수이다.
//StringTokenizer 적용 예시
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
//입력
StringTokenizer st = new StringTokenizer(br.readLine());
//형 변환을 적용한 호출
int i1 = Integer.parseInt(st.nextToken());
int i2 = Integer.parseInt(st.nextToken());
//String.split() 함수 적용 예시
String s = br.readLine();
String[] arr = s.split(" ");
3. BufferedWriter
- BufferedWriter는 System.out.println()과 달리 출력과 개행을 동시에 해주지 않기 때문에, 개행을 위해서는 따로 bw.newLine() 또는 bw.write("\n")을 사용해야 한다.
//선언
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
//문자열 예시
String s = "abcde";
//출력
bw.write(s);
//줄 바꿈
bw.write("\n"); 혹은 bw.newLine();
//남은 데이터 모두 출력
bw.flush();
//닫음
bw.close();
4. StringBuilder
- StringBuilder/StringBuffer는 가변성을 가지기 때문에 append(), delete() 등 동일 객체 내에서 문자열을 변경하는 것이 가능하다. 그렇기 때문에 문자열의 추가, 수정, 삭제가 빈번하게 발생할 경우 유리하다.
- 문자열 연산이 자주 발생하는 단일스레드 환경에서 사용하는 것이 유리하다.
//StringBuilder 사용 예시
StringBuilder sb = new StringBuilder();
sb.append("a");
sb.append("b").append(" ");
sb.append("c").append("\n");
- 주요 메서드
종류 | 설명 |
append(String s) | StringBuilder 뒤에 값을 붙인다. |
delete(int start, int end) | start index부터 end index까지 삭제한다. |
insert(int offset, String s) | 특정 위치에 문자를 삽입한다. |
replace(int start, int end, String s) | start index부터 end index까지를 s 객체로 치환한다. |
reverse() | 순서를 뒤집는다. |
setCharAt(int index, char ch) | 특정 위치 문자를 치환한다. |
indexOf(String s) | 해당 값이 어느 인덱스에 있는지 확인한다. |
subString(int start, int end) | start index부터 end index까지의 값을 자른다. |
4.1 String
- 불변성을 갖기 때문에 concat()이나 + 연산을 통해 값을 변경하면, 기존의 String 메모리에서 값이 바뀌는 것이 아니라 원래 String에 들어 있던 값을 버리고 새로운 값을 재할당하게 된다. 처음에 할당한 String의 메모리 영역은 Garbage로 남아 있다가 GC에 의해 없어진다.
- 불변성을 가지기 때문에 변하지 않는 문자열을 자주 읽어들이는 경우 사용하면 유리하다. 하지만 문자열 연산이 많이 발생하는 경우에 사용하면, heap 메모리에 많은 Garbage가 생성되어 heap 메모리가 부족해져 성능이 저하될 수 있다.
4.2 StringBuilder, StringBuffer 비교
구분 | 설명 |
StringBuilder | - 동기화를 지원하지 않아 멀티스레드 환경에 적합하지 않다. - 단일스레드 환경에서는 StringBuffer 보다 뛰어난 성능을 보여준다. |
StringBuffer | 동기화를 지원하여 멀티스레드 환경에서 안전하다. |
참고
'Java' 카테고리의 다른 글
Abstract Class, Interface 차이점 (0) | 2021.11.25 |
---|---|
JAR, WAR, EAR 차이점 (0) | 2021.11.11 |
HashTable, HashMap, ConcurrentHashMap 차이점 (0) | 2021.10.08 |
SOLID 원칙 (0) | 2021.10.06 |
객체 지향 프로그래밍과 절차적 프로그래밍 (0) | 2021.10.06 |