자바 코딩테스트 기본 문법
1. 프리미티브 타입/레퍼런스 타입
1) 프리미티브 타입/레퍼런스 타입
what?
프리미티브 타입(primitive type): 숫자를 저장하는 기본 데이터 타입
int, long, float, double 등
레퍼런스 타입(reference type): 숫자를 저장하는 래퍼 클래스
Int, Long, Float, Double 등
참조형 변수이므로 연산 속도가 프리미티브 타입보다 느리다.
컬렉션 프레임워크 등에서 정수형 또는 부동소수형을 저장할 때 사용한다.
2)엡실론(epsilon)
what?
자바에서 소수를 계산했을 때 오차가 발생하는 것
why?
자바에서는 부동소수형 데이터를 이진법으로 표현하기 때문에 발생
how?
부동소수형 데이터를 다룰 때 항상 엡실론을 염두에 둬야 한다. 부동소수형 데이터를 활용하는 문제는 오차 허용 범위를 언급하는 경우가 많으므로, 잘 확인하도록 한다.
2. 컬렉션 프레임워크
what?
여러 개의 값을 저장하고 그 값을 효율적으로 다룰 수 있게 하는 표준화 클래스의 집합
리스트, 스택, 큐, 데크, 해시맵 등
*배열
배열은 생성 후에 크기 변경 x -> 새 데이터 삽입, 삭제 불가능. 기존 데이터 변경만 가능
인덱스를 통한 배열 요소에 대한 접근, 변경의 시간 복잡도는 O(1)
1)리스트
코딩 테스트에서는 일반적으로 ArrayList를 의미함
가변 크기 -> 데이터 삽입, 삭제 가능
- 새 데이터를 맨 뒤에 추가할 경우 평균 시간 복잡도 O(1)
- 기존 데이터 삭제 또는 데이터 중간 삽입의 경우 최대 시간 복잡도 O(N)
2)해시맵
키와 값 쌍을 저장하는 해시 테이블로 구성
//초기화
HashMap<String, Integer> map = new HashMap<>();
//값 삽입
map.put("apple pie", 1);
map.put("lemon tart", 2);
map.put("berry jam", 3);
//값 출력
System.out.println(map);
//순서 없이 저장되어서 출력됨
//{lemon tart=2, berry jam=3, apple pie=1}
//값 검색
String key = "apple pie";
if(map.containsKey(key)){
int value = map.get(key);
System.out.println(key + ": " + value);
//apple pie: 1
}
//수정
//키를 검색해서 해당 키의 값을 바꿈
map.put("lemon tart", 4);
//삭제
map.remove("orange");
3)문자열
*문자열은 이뮤터블 객체(값을 변경할 수 없는 객체) -> 시간 복잡도 고려 필요
//문자열 더하기
String string1 = "He";
string1 += "llo";
System.out.println(string1); //Hello
//문자열 수정
String string2 = "Hello";
string2 = string2.replace("l", "");
System.out.println(string2); //"Heo"
이때, String 객체는 값이 변경되지 않는 객체이다. 수정했을 때 실제로는 새로운 객체가 생성된다.
문자열을 더했을 경우 수행되는 연산
- 새로운 String string1 객체 생성
- string1이 가진 "He" 값을 하나씩 복사
- "He" 뒤에 "llo" 저장
∴총 5번의 내부 연산 수행
시간 복잡도 O(N) (문자열의 길이를 N이라고 함)
다음 코드의 시간 복잡도는 O(N^2)
String string3 = "";
for(int i = 1; i <= 100000; i++){
string3 += i;
}
StringBuilder/StringBuffer 클래스 사용
뮤터블한 개체 -> 시간 복잡도 관점에서 훨씬 효율적
다음 코드의 시간 복잡도는 O(N)
StringBuilder string3 = new StringBuilder;
for(int i = 1; i <= 100000; i++){
s.append(i);
}
StringBuilder와 StringBuffer 클래스의 차이: 멀티스레드 환경에서 Thread-Safe 여부
코딩 테스트에서는 다수의 스레드를 생성할 필요가 없지만 Thread-safe가 없는 StringBuilder가 미세하게 빠르므로 StringBuilder를 사용하면 된다.
∴String 값을 변경하는 연산이 많을 때는 StringBuilder를 사용한다.