equals 를 재정의하지 않으면 객체의 주소값만 비교하는 것이 기본 구현입니다.
하지만 객체가 같은 값을 가질 때 같은 객체로 인식하기 위해서는 클래스의 필드에 맞게 재정의가 필요합니다.
hashcode 는 객체간의 구분을 위해 사용하므로 유일하게 객체를 식별할 때 재정의해야 합니다. - Object 의 명세에 의하면 equals 가 동일하면 동일한 해시코드를 반환해야 합니다. 이 때문에 같이 오버라이드 해야합니다.
equals 만 구현했을 때 문제점
hashcode 만 구현했을 때 문제점
hashcode 를 구현할 때 주의할 점
서로 다른 인스턴스더라도 해시코드 값을 가질 수 있습니다. 이때문에 해시 충돌을 해결하는 것이 중요해졌습니다. 해시 충돌을 완화하는 방법에는 크게 Open Addressing 과 Separate Chaining 방식이 존재합니다. 자바의 HashMap 에서는 Separate Chaining 방식을 사용하며, 이는 해시 버킷에 들어갈 수 있는 엔트리의 제한을 두지 않는 방식입니다.
Open Addressing
Separate Chaining
자바에서의 hash 충돌 발생 해결 방법 (HashMap)
String 클래스가 final 로 선언되면서 불변성을 가지게 되었습니다.
이 이유로는 String Pool 을 통한 메모리 절약, 다수의 클래스에 매개변수로 사용되기 때문에 보완 관련 문제, 해시 기반 Collection 의 키 값으로 사용하기 위함 등이 있습니다.
String Pool
Security
Multithreading
- 자바에서 멀티 스레드를 지원하기 위해 String 객체는 thread safe 를 보장해야 한다.
Optimization and Performance
String 은 다른 두 클래스와 다르게 새로운 값을 할당할 때마다 새로운 클래스에 대한 객체가 생성됩니다.
또한 + 연산을 통해 String 객체를 합치는 경우 GC 되기 전까지 메모리에 부하를 주게 됩니다.
이와 반대로 StringBuilder, StringBuffer 는 메모리에 append 하는 방식으로 클래스에 대한 객체를 생성하지 않습니다.
다만 이 둘의 차이는 StringBuilder 는 thread safe 하지 않고, StringBuffer 는 thread safe 하다는 점이 있습니다.
JDK 1.5 이전 버전
JDK 1.5 이후 버전
성능
컬렉션 프레임워크는 다수의 데이터를 쉽고 효과적으로 처리할 수 있는 클래스의 집합입니다.
주요 인터페이스로는 List, Set, Map, Queue 등이 있습니다.
이중 Map 은 다른 것들과 특징이 달라 Collection 을 상속하지 않고 나머지는 Collection 을 상속합니다. 장점으로는 효율적이고 빠른 코드 작성을 할 수 있습니다.
정의: 다수의 데이터를 쉽고 효과적으로 처리할 수 있는 클래스 집합
특징
장점
List 의 구현체로는 ArrayList, LinkedList, Vector, Stack 이 존재합니다.
ArrayList 는 배열처럼 연속된 메모리에 저장되어 검색은 용이하나 삽입, 삭제에는 부적절합니다.
LinkedList 는 양방향 포인터 구조로 데이터 검색보다는 삽입과 삭제가 빈번하게 일어나는 경우에 유용합니다.
Vector 는 ArrayList 와 동일하게 배열로 구현되어있고 내부에서 동기 처리가 일어나는 것이 특징입니다.
마지막으로 Stack 은 Vector 를 상속받아 동기 처리가 일어납니다.
ArrayList
LinkedList
Vector
class MyList {
ArrayList<T> list = new ArrayList<>(Collections.synchronizedList());
}
Stack
| List | Set |
|---|---|
| indexed sequence | non-indexed sequence |
| 중복 허용 | 중복 허용 X |