📌 각각 어떤 상황에서 HashMap과 TreeMap을 선택하나요?
A. HashMap은 순서가 중요하지 않고 빠른 검색, 삽입, 삭제가 필요한 경우에 적합합니다. TreeMap은 키를 기준으로 정렬된 순서를 유지해야 하거나 범위 기반 검색이 필요한 경우에 유용합니다.
HashMap
- Map 인터페이스를 상속 → Map은 키와 값으로 구성된 Entry객체를 저장하는 구조를 가지고 있는 자료구조
- 키와 값은 모두 객체
- 해싱(Hashing)을 사용하기 때문에 많은 양의 데이터를 검색하는 데 있어서 뛰어난 성능을 보임
- 해시맵은 키의 순서를 보장하지 않습니다. 삽입 순서나 특정 순서로 반복해서 접근하는 것을 보장하지 않습니다.
- 순서가 중요하지 않고, 빠른 검색, 삽입 및 삭제 연산이 필요한 경우에 적합
참고 : https://coding-factory.tistory.com/556
TreeMap
- 이진트리를 기반으로 한 Map 컬렉션
- 키와 값이 저장된 Map, Etnry를 저장
- 객체를 저장하면 자동으로 정렬되는데, 키는 저장과 동시에 자동 오름차순으로 정렬되고 숫자 타입일 경우에는 값으로, 문자열 타입일 경우에는 유니코드로 정렬함
참고 : https://coding-factory.tistory.com/557
📌 HashMap 구현 원칙은 무엇인가요?
A.
- 해시 함수 선택
: 키를 해시 코드로 변환하는 함수를 선택하고, 좋은 분포와 충돌 최소화를 위해 신중하게 설계합니다.
- 해시 충돌 처리
: 서로 다른 키들이 같은 해시 코드를 가질 수 있으므로 충돌을 처리하는 방식을 결정합니다.
- 초기 용량 및 로드 팩터 설정
: 초기 용량과 로드 팩터를 적절하게 선택하여 HashMap의 성능을 최적화합니다.
- 동기화
: 멀티스레드 환경에서 사용할 경우 동기화를 고려하여 스레드 안전성을 확보합니다.
- 객체의 동등성 비교
: 키 객체의 동등성을 판단하기 위해 hashCode()
와 equals()
메서드를 오버라이딩하여 정확한 비교를 수행합니다.
- 메모리 사용과 성능
: 적절한 초기 용량과 로드 팩터를 선택하여 메모리 사용을 최적화하고, 해시 함수와 충돌 처리 방법을 효율적으로 구현하여 성능을 향상시킵니다.
📌 HashSet 구현 원칙은 무엇인가요?
A.
- 해시 함수 선택: 키의 해시 코드를 계산하기 위한 해시 함수를 선택하고, 좋은 분포와 충돌 최소화를 위해 신중하게 설계합니다.
- 해시 충돌 처리: 해시 함수를 사용하면 서로 다른 키들이 같은 해시 코드를 가질 수 있으므로 충돌 처리 방식을 결정합니다. 주로 체이닝(연결 리스트)을 사용하여 충돌하는 요소를 같은 버킷에 연결하는 방식을 선택합니다.
- 초기 용량 및 로드 팩터 설정: 초기 용량과 로드 팩터를 적절하게 선택하여 HashSet의 성능을 최적화합니다.
- 동기화: 멀티스레드 환경에서 사용할 경우 동기화를 고려하여 스레드 안전성을 확보합니다.
- 객체의 동등성 비교: 객체의 동등성을 판단하기 위해
hashCode()
와 equals()
메서드를 적절하게 오버라이딩하여 정확한 비교를 수행합니다.
- 메모리 사용과 성능: 적절한 초기 용량과 로드 팩터를 선택하여 메모리 사용을 최적화하고, 해시 함수와 충돌 처리 방법을 효율적으로 구현하여 성능을 향상시킵니다.
Set 이란?
- 중복되지 않는 원소들을 저장하는 자료구조 → 순서를 보장하지 않으며, 각 원소는 고유해야 함
- 삽입(insertion) 순서대로 저장되지 않는다. 즉 특정한 순서를 기대할 수 없는 자료구조.
- 수정 가능함
- 중복을 허용하지 않고 고유한 원소를 관리해야 할 때 유용
HashSet이란?
- 중복을 허용하지 않고, 원소들을 순서 없이 저장하는 자료구조
- 순서 없음 → HashSet은 원소들을 저장한 순서를 유지하지 않습니다. 따라서 HashSet에서 원소를 순서대로 접근하기 위해서는 Iterator를 사용해야 합니다.
- Null 원소 허용 → HashSet은 null 값을 원소로 가질 수 있습니다. null 원소도 중복되지 않으며, 하나의 null 원소만 저장됩니다.
📌 ArrayList와 LinkedList의 차이점은 무엇인가요?
A. ArrayList는 요소의 접근이 빠르고 메모리를 효율적으로 사용하는 반면, LinkedList는 요소의 추가/삭제가 빠르고 메모리 사용이 유연합니다. 선택은 데이터의 특성과 사용 패턴에 따라 달라집니다. 대체로 데이터를 자주 추가/삭제해야 한다면 LinkedList를, 데이터 접근이 주로 필요하다면 ArrayList를 사용하는 것이 적합합니다.
ArrayList
- Collection 프레임워크의 일부이며 java.util 패키지에 소속되어 있음
- 내부적으로 배열(Array)을 사용하여 요소를 저장
- 요소의 추가/삭제가 느림 → 중간에 요소를 삽입하거나 삭제할 경우, 해당 위치 이후의 모든 요소들을 이동시켜야함
- 인덱스를 사용하여 빠르게 요소에 접근 가능
- 메모리를 연속적으로 할당하고 사용

LinkedList
- List를 구체화한 클래스
- 각의 노드를 연결하는 방식을 사용
- 양방향 연결 리스트(Doubly Linked List)로 구현 → 각각의 데이터가 노드(Node)로 구성되어 연결이 되는 구조
- 내부적으로 연결 리스트(Linked List)를 사용하여 요소를 저장 → 이전 요소와 다음 요소에 대한 참조를 가지고 있음
- 각 요소는 이전 요소와 다음 요소에 대한 참조를 가지고 있기 때문에 삽입 또는 삭제 시에 참조만 변경하면 됨

참고 : https://coding-factory.tistory.com/551
https://psychoria.tistory.com/767
📌 Array에서 List로 전환하려면 어떻게 해야하나요?
A.
-
Arrays.asList() 메서드 사용
- Arrays 클래스의
asList()
메서드를 사용하여 Array를 List로 변환 가능
- 이 방법은 고정 크기의 리스트를 생성하며, 원본 배열과 리스트 사이에는 백업이 이루어지지 않습니다.
public static void main(String args[]) {
Integer[] intArray = {1, 3, 5, 7, 9};
List<Integer> intList = Arrays.asList(intArray);
System.out.println("intList: " + intList);
String[] strArray = {"A", "AB", "ABC"};
List<String> strList = Arrays.asList(strArray);
System.out.println("strList: " + strList);
Boolean[] boolArray = {true, false, true};
List<Boolean> boolList = Arrays.asList(boolArray);
System.out.println("boolList: " + boolList);
}
-
ArrayList 또는 LinkedList 생성자 사용
- List 구현 클래스의 생성자를 사용하여 Array를 List로 변환 가능
- 이 방법은 새로운 List 인스턴스를 생성하므로, 리스트에서의 변경은 원본 배열에 영향을 주지 않습니다.
- ArrayList:
List<T> list = new ArrayList<>(Arrays.asList(array));
- LinkedList:
List<T> list = new LinkedList<>(Arrays.asList(array));
-
직접 원소 추가
- 새로운 ArrayList 또는 LinkedList를 생성한 후, 반복문을 사용하여 Array의 원소를 하나씩 리스트에 추가
List<T> list = new ArrayList<>();
for (T element : array) {
list.add(element);
}
참고 : [Java]배열을 리스트로 변환(Array to List)