01 프리미티브 타입과 레퍼런스 타입
프리미티브 타입과 레퍼런스 타입
Primitive type | int,long,float, double | 연산 속도 빠름 |
Reference type | Integer, Long, Float, Double | 연산 속도 느림 (참조형 변수) 컬렉션 프레임워크에서 정수형 또는 부동소수형 저장할 때 사용 |
정수형
//정수형 변수 선언
int a = 13;
int b = 4;
//정수형 산술 연산
System.out.println(a+b); // + - * / %
//정수형 비교 연산
System.out.println(a==b); // == != > < >= <=
//정수형 비트 연상
System.out.println(a&b); // & | ^ ~ << >>
부동소수형
//부동소수형 모듈러 연산
System.out.println(10.0 % 3.2);
> 0.39999999999999947
- 0.4가 아닌 이유는 자바는 부동소수형 데이터를 이진법으로 표현하기 때문입니다.
- 그렇기 때문에 표현 과정에서 오차가 발생하는데 이를 앱실론(epslion)이라 합니다.
- 앱실론 때문에 부동소수형 데이터를 다룰 때 주의해야합니다. (테스트 케이스 통과 못할 수도있음)
02 컬렉션 프레임워크
컬렉션 프레임워크
- 여러 개의 값을 저장하고 그 값을 쉽고, 효율적이게 처리해주는 표준화 클래스의 집합입니다.
- 리스트, 큐, 해시맵 등의 자료구조를 직접 구현하지 않고도 손쉽게 사용할 수 있게 해줍니다.
- ArrayList, Stack, Queue, ArrayDeque, HashMap등이 있습니다.
배열
//배열의 생성
int[] array = {1,2,3,4,5};
//배열의 출력
System.out.println(Arrays.toString(array));
> [1,2,3,4,5]
//배열의 인덱스 (시간 복잡도 O(1))
System.out.println(array[2]);
> 3
리스트
- 배열은 크기가 고정되어 있지만, ArrayList는 가변적입니다.
- 새 데이터의 삽입 혹은 기존 데이터 삭제가 용이합니다.
- 새 데이터를 맨 뒤에 추가할 때는 시간 복잡도가 O(1)지만, 기존 데이터 삭제, 데이터 중간 삽입 때는 O(N)까지 커질 수 있습니다.
//리스트 객체 생성
ArrayList<Integer> list = new ArrayList<>();
//값 추가
list.add(1);
list.add(2);
System.out.println(list.get(0));
> 1
System.out.println(list);
> [1,2]
해시맵
- Java의 해시맵은 key, value 쌍을 저장하는 해시 테이블로 구현되어 있습니다.
- 키를 사용하여 값을 검색하는 자료 구조입니다.
//해시맵 초기화
HashMap<String, Integer> map = new HashMap<>(); //key : 문자열, value : 정수형
//해시맵 값 삽입
map.put("apple",1);
map.put("banana",2);
//해시맵 값 출력
System.out.println(map);
> {banana=2, apple=1}
//해시맵의 데이터 검색
String key = "apple";
if(map.containsKey(key)) {
int value = map.get(key);
System.out.println(key + value);
} //없을 때 예외처리
//해시맵 수정
map.put("banana",4); //banana:4
//해시맵 삭제
map.remove("apple");
문자열
- 이뮤터블(Immutable) 객체 : 값을 변경할 수 없는 객체를 의미합니다. 따라서 시간 복잡도 관점에서 사용 시 주의해야 합니다.
- 문자열은 문자들의 배열 형태로 구성한 이뮤터블 객체입니다.
- 문자열의 추가, 삭제는 기존 객체를 수정하는 것이 아니라 새로운 객체를 반환합니다.
//문자열 초기화
String str = "Hello, World!"
//문자열 수정
str = string.replace("l", "");
//StringBuffer와 StringBuilder
System.out.println(System.identityHashCode(str));
> 1808253012
str += "test"
System.out.println(System.identityHashCode(str));
> 589431969
- System.identityHashCode() 메소드는 식별값을 반환합니다.
- 앞의 str과 뒤의 str은 식별값이 다르므로 서로 다른 객체임을 의미합니다.
- 즉, String 객체의 값을 변경하는 작업은 새로운 String 객체를 만들고 값을 복사하는 작업이 수행됨을 의미합니다.
- 내부에서는 다음과 같은 연산이 수행됩니다.
- 새로운 String str 객체 생성
- str 내부 값을 하나씩 복사
- 기존 str 뒤에 test 저장
- 문자열의 길이를 N이라 했을 때 O(N)이 됩니다.
- for문으로 문자열을 추가 한다고 했을 때 시간 복잡도는 O(N^2)이 되기 때문에 효율이 좋지않습니다.
- 그래서 StringBuilder와 StringBuffer 클래스를 사용합니다.
//StringBuilder 클래스 활용
long start = System.currentTimeMillis(); //시작 시간
StringBuilder sb = new StringBuilder();
for(int i = 0 ; i < 100_000 ; i++) {
sb.append(i);
}
long end = System.currentTimeMillis(); //종료 시간
System.out.println((end-start)/1000.0+"초");
//StringBuilder 클래스 활용2
sb.append(10);
sb.append("ABC");
System.out.println(sb); //10ABC
sb.deleteCharAt(3); //10AC
sb.insetr(1,2) //120AC
- StringBuffer와 StringBuilder의 차이는 멀티스레드 환경에서 Thread-Safe 여부로 나뉩니다.
- 하지만 코딩 테스트에서는 다수의 스레드를 생성할 필요가 없기 때문에 StringBuilder를 사용하면 됩니다.
- String값의 연산이 많으면 시간 초과가 발생하지 않도록 StringBuilder를 꼭 사용하세요!
03 메서드
람다식
- lambda expression은 다른 말로 익명 함수(anonymous function)이라고도 합니다.
- 익명 함수 : 이름이 없는 함수를 말하며 코드에서 딱 한 번 실행할 목적ㅇ로 사용하거나 함수 자체를 다른 함수의 인수로 전달할 때 도 사용할 수 있습니다. 또한 람다식을 사용하면 함수를 더 간결하게 표현할 수 있고 가독성이 좋아집니다.
//람다식 정의
private static class Node {
int a, b;
public Node(int a, int b) {
this.a = a;
this.b = b;
}
}
public static void main(String[] args) {
Node[] nodes = new Node[3];
nodes[0] = new Node(1, 10);
nodes[1] = new Node(2, 20);
nodes[2] = new Node(3, 30);
//람다식
Arrays.sort(nodes, (o1, o2) -> Integer.compare(o1.cost, o2.cost));
//람다식 아님
Arrays.sort(nodes, new Comparator<Node>() {
@Override
public int compare(Node o1, Node o2) {
return Integer.compare(o1.b, o2.b) //b 기준 오름차순
}
});
}
- Integer.compare(int x, int y) 메서드는 다음과 같이 동작합니다
- x < y : return -1
- x > y : return 1
- x == y : return 0
04 코딩 테스트 코드 구현 노하우
조기 반환 (early return)
- 함수가 끝까지 도달하기 전 return 하는 기법입니다.
보호 구문 (guard clauses)
- 본격적인 로직을 진행하기 전 예외 처리 코드를 추가하는 기법입니다.
제네릭 (generic)
- 빌드 레벨에서 타입을 체크하여 타입 안정성을 제공하고, 타입 체크와 형변환을 생략할 수있게 해줍니다.
'알고리즘 공부' 카테고리의 다른 글
02 알고리즘의 효율 분석 (0) | 2025.05.25 |
---|---|
01 코딩 테스트 준비하기 (0) | 2025.05.23 |
[알고리즘] Part09 | 시뮬레이션 (1) | 2025.02.18 |