import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
long a = sc.nextLong();
long b = sc.nextLong();
long c = sc.nextLong();
System.out.println(sum(a,b,c));
}
public static long sum(long a, long b, long c) {
return a+b+c;
}
}
2. BufferedReader 사용 예제
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); // 선언
StringTokenizer st = new StringTokenizer(br.readLine());
long a = Long.parseLong(st.nextToken());
long b = Long.parseLong(st.nextToken());
long c = Long.parseLong(st.nextToken());
System.out.println(a + b + c);
}
}
buffer에서 readLine을 할때마다 try & catch를 활용하여 예외처리 또는 메인 함수에 throws IOException을 통하여 작업해야합니다. 그렇지 않으면 오류가 나타납니다.
위의 두 코드는 모두 세 수의 합을 출력할 수 있습니다.
NO
입력
시간
1
Scanner
204ms
2
BufferedReader
120ms
하지만 이렇게 위의 표를 보시면 속도 차이를 볼 수 있습니다.
입력 값이 적기 때문에 시간이 2배 정도 차이가 나는 것이고 만약 더 많은 입출력이 있다면 그때는 속도, 시간 차이가 더 확실하게 나타날 것입니다.
3. Buffer의 사용 방법
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); // 선언
long a = Long.parseLong(br.readLine());
long b = Long.parseLong(br.readLine());
long c = Long.parseLong(br.readLine());
System.out.println(a + b + c);
}
}
// 77 77 7777
// Exception in thread "main" java.lang.NumberFormatException: For input string: "77 77 7777"
// at java.base/java.lang.NumberFormatException.forInputString(NumberFormatException.java:67)
// at java.base/java.lang.Long.parseLong(Long.java:711)
// at java.base/java.lang.Long.parseLong(Long.java:834)
// at backjoon.Main_꼬마정민3.main(Main_꼬마정민3.java:17)
위의 코드처럼 br.readLine()로 여러번 입력을 받게되면 오류가 뜨게됩니다.
따라서 여러 수를 사용할 때는 StringTokenizer로 입력을 받은 후 가공을 하면 됩니다.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); // 선언
StringTokenizer st = new StringTokenizer(br.readLine());
long a = Long.parseLong(st.nextToken());
long b = Long.parseLong(st.nextToken());
long c = Long.parseLong(st.nextToken());
System.out.println(a + b + c);
}
}
위의 방법대로 StringTokenizer를 사용하여 변수 선언을 별도로 해주면 빈칸의 존재 여부에 따라서 자동으로 변수에 저장할 수 있습니다.
별도의 배열을 생성한 후 split을 사용해서 아래와 같이 변수로 지정할 수 있습니다.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); // 선언
String s = br.readLine();
String str[] = s.split(" ");
long sum = 0;
for(int i = 0; i<str.length; i++) {
sum += Long.parseLong(str[i]);
}
System.out.println(sum);
}
}
◎ BufferedReader 클래스 메소드
NO
Type
메소드
기능
1
void
close()
입력 스트림을 닫고, 사용하던 자원을 해제
2
void
mark(int, readAheadLimit)
스트림의 현재 위치를 마킹
3
int
read()
한 글자만 읽어 정수형으로 반환
4
String
readLine()
한 줄을 읽음
5
boolean
ready()
입력 스트림이 사용할 준비가 되었는지 확인(1이면 준비 완료)
4. BufferedWriter 사용법
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); // 선언
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
String s = br.readLine();
String str[] = s.split(" ");
String sum = "";
for(int i = 0; i<str.length; i++) {
sum += str[i];
bw.write(sum);
bw.newLine();
}
br.close();
bw.flush();
bw.close();
}
}
// 입력 : a bc def
// 출력 :
// a
// abc
// abcdef
일반적으로 출력할 때는 System.out.println()을 사용하면 되지만 양이 많아질 경우에는 입력과 동일하게 Buffer를 사용해야합니다.
줄바꿈을 하기 위해서는 newLine() 또는 bw.write("\n")을 사용해야합니다. 또한, 사용하고 난 후 flush()를 통해 남아 있는 것들을 모두 출력하고 close()를 통해 buffer를 닫아줍니다.
◎ BufferedWriter 클래스 메소드
NO
Type
메소드
기능
1
void
close()
스트림을 닫음
2
void
flush()
스트림을 비움, 스트림을 닫기 전 수행
3
void
newLine()
한 줄을 띄움
4
void
write(char[] buf, int offset, int length)
버퍼 offset 위치부터 length 크기만큼 write
5
void
write(int c)
한 글자 쓰기
6
void
write(String s, int offset, int length)
문자열 offset에서부터 length 길이만큼 write
5. StringBuilder
마지막으로 StringBuilder에 대해서 알아보겠습니다!
1. String String은 불변의 속성을 가지므로 concat, + 연산 등을 통해 값이 변경되면 기존의 String 메모리에서 값이 바뀌는 것이 아니라, 기존의 String에 있던 값을 버리고 새로운 값을 재할당합니다.
문자열을 자주 읽어들이면 유리하지만 추가, 삭제, 수정 등의 연산 등이 자주 일어나는 경우에 사용하게 되면 힙 메모리에 많은 Garbage가 생성되고 힙 메모리가 부족하게 되는 현상이 발생할 수 있습니다.
2. StringBuffer/ StringBuilder String의 문제를 해결하기 위해 사용하는 것이고 가변성을 가집니다.
.append(), .delete() 등을 사용해서 동일 객체 내에서 문자열을 변경하는 것이 가능합니다.
출처 : javapapers.com 위의 사진을 보면 append를 사용한 것이 훨씬 빠른 것을 볼 수 있습니다.
◎ StringBuilder 사용 예제
public class Main {
public static void main(String[] args) {
StringBuilder sb = new StringBuilder();
sb.append("1");
sb.append("a").append("\n");
sb.append("2").append(" ").append("b");
System.out.println(sb);
}
}
// 출력 :
// 1a
// 2 b
◎ StringBuilder 메소드
NO
메소드
기능
1
append(String s)
StringBuilder 뒤에 값을 붙음
2
delete(int start, int end)
특정 인덱스부터 인덱스까지를 삭제
3
insert(int offset, any primitive of a char[])
문자를 삽입함
4
replace(int start, int end, String s)
일부를 String 객체로 치환
5
reverse()
순서를 뒤집음
6
setCharAt(int index, char ch)
주어진 문자를 치환
7
indexOf(String s)
값이 어느 인덱스에 들어있는지 확인
8
subString(int start, int end)
start와 end 사이의 값을 잘라옴
이렇게 Buffer를 통한 입출력에 대해서 알아보았습니다.
이제 입출력 문제를 풀때 Scanner와 Buffer 둘 다 이용해보는 방법을 사용하면서 공부를 해야겠어요!!