Java - 더 빠른 입출력을 구현하기 위한 여정

StringTokenizer와 BufferedReader 콤비네이션

Posted by Yan on August 5, 2021

BufferedReader

  • 버퍼를 이용해서 읽고 쓰는 것
  • Scanner보다 입출력의 효율이 좋아진다.
  • 하드디스크는 원래 속도가 느리고, 외부장치와의 입출력은 생각보다 시간이 걸리는 작업이다. 따라서 데이터를 바로 목적지로 이동시키는 것보다 메모리 버퍼를 두어 데이터를 한번에 묶어서 이동시키는 것이 효율적이고 빠르다.

Scanner와의 차이

  • Scanner는 띄어쓰기와 개행문자를 경계로 입력값을 인식하기 때문에 가공할 필요가 없어서 사용하기 편하다
  • BufferedReaderInputStreamReader로 값을 입력받을건데, 엔터만 경계로 인식하고 받은 데이터는 String으로 고정된다.

StringTokenizer

  • 특정 문자에 따라 문자열을 나누고 싶을 때 사용한다
  • String + Tokenizer = 문자열을 토큰화하여 쪼갠다.
  • BufferedReader로 받아온 문자열을 특정 문자열을 기준으로 나눌 때 사용하기 좋다.

생성 방식

1
2
3
4
5
6
7
8
StringTokenizer st = new StringTokenizer(문자열); 
//띄어쓰기 기준 문자열 분리

StringTokenizer st = new StringTokenizer(문자열, 구분자); 
//구분자 기준 문자열 분리

StringTokenizer st = new StringTokenizer(문자열, 구분자, true or false); 
//구분자 기준 문자열 분리 + 구분자도 토큰으로 넣기(true), default는 false

메소드

return value method name do what?
String nextTokens() 객체에서 다음 토큰을 반환
String nextToken(String delim) delim기준으로 다음 토큰을 반환
boolean hasMoreTokens() 남아있는 토큰이 있으면 true를 리턴, 더 이상 토큰이 없으면 false 리턴
boolean hasMoreElements() hasMoreTokens와 동일한데 보통 hasMoreTokens를 더 많이 쓴다
Object nextElement() nextToken과 동일하지만 문자열이 아닌 객체를 리턴한다
int countTokens() 총 토큰의 갯수를 리턴한다

빠른 입출력 구현코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
    static class FastReader {
        BufferedReader br;
        StringTokenizer st;

        public FastReader() {
            br = new BufferedReader(new InputStreamReader(System.in));
        }

        String next() {
            while (st == null || !st.hasMoreElements()) {
                try {
                    st = new StringTokenizer(br.readLine());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            return st.nextToken();
        }

        int nextInt() {
            return Integer.parseInt(next());
        }

        long nextLong() {
            return Long.parseLong(next());
        }

        double nextDouble() {
            return Double.parseDouble(next());
        }

        String nextLine() {
            String str = "";
            try {
                str = br.readLine();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return str;
        }
    }

reference

[Java 자바 입출력] BufferedReader/BufferedWriter [Java 자바] StringTokenizer 클래스로 문자열 분리하기! split비교.