본문 바로가기
Language & Tool/Java

🌱기본 입출력

by 박수무당벌레 2025. 9. 8.

입력

기본 입력 (Scanner)

  • 간단, 느림
  • 입력 크기가 크면 비권장 (10^3 ~ 10^4 이)
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);

        int n = sc.nextInt();    // 정수 입력
        String s = sc.next();    // 문자열 입력 (공백 기준)
        String line = sc.nextLine(); // 한 줄 전체 입력
    }
}
※ System.in : InputStream 객체, 콘솔에서 입력 받는 바이트 스트림

 

 

빠른 입력 (BufferedReader + StringTokenizer)

  • BufferedReader : 문자를 한 줄 단위(readLine())로 빠르게 읽을 수 있도록 버퍼를 붙인 클래스
  • InputStreamReader : 바이트 → 문자로 변환해주는 문자 스트림 래퍼(wrapper)
  • br.readLine().trim()  : 입력한 한줄 전체 문자열 읽기 + 양쪽 공백 제거
  • Integer.parseInt(...) : 문자열  → 정수 변환
  • new StringTokenizer(...)  : 공백 기준 으로 문자열을 잘라서 토큰(단어) 단위로 관리 (토큰 차례대로 저장)
    .nextToken() 호출 할떄마다 하나씩 꺼낼 수 있음
        ( StringTokenizer = 상태를 유지하며 토큰을 순차적으로 꺼내는 절차적 방식)
    java.util 패키지 포함
  • 데이터가 큰 10^5 수준 무난히 처리 (빠른 I/O가 필요한 경우)
  • while (!st.hasMoreTokens()) ... : 남은 토큰 확인 확인(hasMoreTokens) 으로 토큰이 없다면, 다음 줄 읽어서 새로운 StringTokenizer를 재할당
import java.io.*;
import java.util.StringTokenizer;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

        int n = Integer.parseInt(br.readLine()); // 한 줄 입력 후 int 변환
        StringTokenizer st = new StringTokenizer(br.readLine());

        int a = Integer.parseInt(st.nextToken());
        int b = Integer.parseInt(st.nextToken());
        
        // ➕ 혹은 명확하게 M개의 요소를 받아야할때 while + hasMoreTokens 사용
        for (int i = 0; i < M; i++) {
            while (!st.hasMoreTokens()) st = new StringTokenizer(br.readLine());
            int x = Integer.parseInt(st.nextToken());
            ...
        }

        System.out.println(a + b);
    }
}

 

 

Arrays.stream(...).mapToInt(...).toArray()

  • Stream API 이용한 처리
  • .trim() : 입력 받은 양끝 공백 정리
    문자열 시작/끝 에 공백이 있으면, split("\\s+") 가 맨 앞(혹은 뒤) 에 빈 문자열 토큰 을 만들 수 있음 (사전 제거용)
  • .split("\\s+") : 정규식 으로 문자열을 구분자 기준 토큰 배열로 나눔(공백 기준), 결과 타입은 String[]
      \\s : 문자열에서  를 한 번 더 이스케이프해야 함 (∴  \\ 가 실제 정규식의  )
     \s  :  공백 문자 클래스 (스페이스 뿐만 아니라 탭, 줄바꿈 등) 의미
      : 하나 이상 연속 의미 (= 공백이 1개든 10개든 한 구분자로 취급) 
    ※ 단순 스페이스만 자르려면 " +"  도 충분 (여러 스페이스)
  • Arrays.stream(...)  : 문자열 배열을 스트림 으로 변환
    String[]  에서  Stream<String>  으로 변환
        ( Arrays.stream(int[]) 라면 IntStream )
  • .mapToInt(Integer::parseInt) : 각 문자열 토큰 정수 변환 ( 박싱 없이 바로 int로 변환 )
    → Integer::parseInt : s -> Integer.parseInt(s) 와 동일한 메서드 레퍼런스 문법
  • .toArray(Integer[]::new) : 위(.map(Integer::parseInt)) 대신 사용 가능 , But. Integer[] 로 박싱 비용이 늘어남(메모리/GC▲)
  • .toArray() : 변환된 값을 원시 타입 배열인 int[] 로 수집/반환
  • 예외 발생 지점:
    ①  숫자가 아닌 토큰(ex. "1,2,3", "10a") 이 섞이면 parseInt 에서 예외 발생
      빈 줄 입력시, parseInt("") 에서 예외 발생 주의 (혹은 아래처럼 가드 코드)
        String line = br.readLine();
        line = (line == null) ? "" : line.trim();
        if (line.isEmpty()) return new int[0]; // 혹은 예외 처리
  • StringTokenizer 가 대체로 더 빠름
    → String.split 은 정규식을 매번 해석함, 비용 있음(오버헤드▲)
    → 공백이 단순하면 직접 루프 파싱이 가장 빠
int[] a = Arrays.stream(br.readLine().trim().split("\\s+"))
                .mapToInt(Integer::parseInt)
                .toArray();

 

 

출력

기본 출력

System.out.println("Hello");  // 줄바꿈 출력
System.out.print("Hello");    // 줄바꿈 없이 출력
System.out.printf("나이: %d\n", 20); // 형식 지정 출력
※ 출력 내용 마지막에 "\n" 이 포함되어 있으면 print()가 적합, 하나씩 바로 찍을거면 println() 사용

 

 

빠른 출력 (BufferedWriter, StringBuilder)

 

- BufferedWriter

import java.io.*;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));

        bw.write("Hello\n");
        bw.write("World\n");

        bw.flush();  // 반드시 flush 해야 출력됨
        bw.close();
    }
}

 

- StringBuilder

  • 문자열을 합칠 때 사용 (대부분의 경우 권장)
  • String은 불변,  로 붙일때마다 새로운 객체가 생성됨  (O(N²))
    → 반복시 문자열 길이에 비례해서 메모리 낭비, 성능 저하
  • StringBuilder는 가변 (내부 버퍼를 재활용함) → 연결 속도가 훨씬 빠름 (O(N))
  • 문자열 누적, 수천글자 이상 생성 시 필요
  • java.lang 패키지 포함
StringBuilder sb = new StringBuilder();
sb.append("Hello\n");
sb.append("World\n");
System.out.print(sb);

 

 

요약 정리

 

- 요약 정리

  • 입력 데이터 크기가 작으면 Scanner + System.out.println 도 가능
  • 입력 데이터 크기가 크면 반드시 BufferedReader + StringTokenizer + StringBuilder 조합
  • Integer.parseInt(), Long.parseLong() 변환 필수
    → 사전 String 변환 필요함
  • 배열 입력 받을 때는 for문과 StringTokenizer 함께 사용

 

- (예시)입력

5
1 2 3 4 5

 

- 빠른 입출력

import java.io.*;
import java.util.StringTokenizer;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringBuilder sb = new StringBuilder();

        int n = Integer.parseInt(br.readLine());
        StringTokenizer st = new StringTokenizer(br.readLine());

        int sum = 0;
        for (int i = 0; i < n; i++) {
            sum += Integer.parseInt(st.nextToken());
        }

        sb.append(sum).append("\n");
        System.out.print(sb);
    }
}