• 컬랙션 프레임워크에 저장할 수 있는 데이터는 오직 객체이다.
  • 원시 타입은 박싱하여 저장해야 하며, 주소값을 담는 것이므로 null도 저장이 가능하다.

종류

  • ListSet 인터페이스를 구현한 컬렉션 클래스들은 공통부분이 많아, Collection 인터페이스로 상속되어 있다.
  • Map 인터페이스 컬렉션들은 두개의 데이터를 묶어 한쌍으로 다루기 때문에 Collection 인터페이스와 분리되어 있다.

Iterable 인터페이스

  • 컬렉션 인터페이스들의 가장 최상위 인터페이스
  • Iterator

    ArrayList, HashSet과 같은 컬렉션을 반복하는 데 사용할 수 있는 객체
    • for-each와 비교되는 장점
      • 컬렉션에서 요소를 제어할 수 있다.(반복하는 동안 요소를 제거할 수 있다.)
        • for-each문으로 자료구조를 돌다가 값을 수정, 삭제하는 경우, ConcurrentModificationException이 발생한다.
      • next()previous()를 써서 앞뒤로 이동할 수 있다.
      • hasNext()를 써서 더 많은 요소가 있는지 확인할 수 있다.
Iterator<String> iterator = cars.iterator();
 
// iterator 출력
while(iterator.hasNext()){
System.out.println(iterator.next());
}
 
// for-each 출력
for(String str : cars){
System.out.println(str);
}
 
// iterator 삭제
while(iterator.hasNext()){
System.out.println("iter.next(): ") + iterator.next())
iterator.remove()
}
 
// iterator 수정
while(iterator.hasNext()){
Object element = iterator.next();
iterator.set(element + "+");
}

Collection 인터페이스

  • 컬렉션 프레임워크에서 가장 기본이 되는 interfaceCollection 인터페이스이다.
    • 중복도 허용하고, 자료가 저장된 순서도 기억하지 못한다.
    • add(), size(), iterator(), … 메소드가 있다.
    • 저장된 순서를 기억하지 못하기 때문에 저장된 자료를 하나씩 꺼내 쓸 수 있는 iterator 인터페이스를 반환한다.
      • Iterator는 꺼낼것이 있는지 없는지 살펴보는 hasNext()메소드와 하나씩 자료를 꺼낼때 사용하는 next()메소드를 가지고 있다.

List

  • 중복을 허용하면서 순서를 기억하는 자료구조
  • Collection 인터페이스를 상속받는다.
  • get(int) 메소드로 n번째 자료를 꺼낼 수 있다.
  • 배열과 마찬가지로 index로 요소에 접근한다.
  • 자료형의 크기가 고정이 아닌 데이터의 양에 따라 동적으로 늘었다 줄어들 수 있다.
  • 요소 사이에 빈 공간을 허용하지 않아 삽입/삭제 할때마다 배열 이동이 일어난다.

ArrayList 클래스

  • 단방향 포인터 구조로 자료에 대한 순차적인 접근에 강점이 있어 조회가 빠르다.
  • 삽입/삭제가 느리다. 단, 순차적으로 추가/삭제 하는 경우에는 가장 빠르다.

LinkedList 클래스

  • 노드(객체)를 연결하여 리스트처럼 만든 컬렉션
  • 중간 삽입, 삭제가 빈번할 경우 빠른 성능을 보장한다.
  • 임의의 요소에 대한 접근 성능은 좋지 않다.
  • 리스트 이외에도 스택, 큐, 트리 등의 자료구조의 근간이 된다.

Vector 클래스

  • ArrayList의 구형 버전
  • 동기화가 되어 있어 Thread-Safe하지만, 잘 쓰지 않는다.
  • 협업에서 컬렉션에 동기화가 필요하면 Collections.synchronizedList() 메서드를 이용해 ArrayList를 동기화 처리하여 사용한다.

Stack 클래스

  • 후입선출(LIFO) 자료구조
  • Vector를 상속하기 때문에 문제점이 많아 잘 안쓴다. ==(대신 ArrayDeque 사용)==

Queue 인터페이스

  • 선입선출 FIFO 구조

PriorityQueue 클래스

  • 우선 순위(priority)를 부여하여 우선 순위가 높은 순으로 정렬되고 꺼낸다.
  • 수행할 작업이 여러개 있고 시간이 제한되어 있을 때 우선순위가 높은 것부터 수행할 때 쓰인다.
  • 우선순위 큐에 저장할 객체는 필수적으로 Comparable 인터페이스를 구현해야 한다.
    • compareTo() 메서드 로직에 따라 자료 객체의 우선순위를 결정하는 식으로 동작한다.
  • 저장공간으로 배열을 사용하며, 각 요소를 힙(heap) 형태로 저장한다.
    • 힙은 이진 트리의 한 종료로 우선순위가 가장 높은 자료를 루트 노드로 갱신한다는 점으로, 가장 큰 값이나 가장 작은 값을 빠르게 찾을 수 있다는 특징이 있다.
  • null 저장 불가능
Queue Student implements Comparable<Student>{
	String name;
	int priority;
	
	// 생성자  생략
 
	@Override
	public int comapreTo(Student user){
		if (this.priority < user.priority) {
			return -1;
		} else if (this.priority == user.priority){
			return 0;
		} else{
			return 1;
		}
	}
}
 
public static void main(String[] args){
	Queue<Student> priorityQueue = new PriorityQueue<>();
 
    priorityQueue.add(new Student("주몽", 5));
    priorityQueue.add(new Student("세종", 9));
    priorityQueue.add(new Student("홍길동", 1));
    priorityQueue.add(new Student("임꺽정", 2));
 
    // 우선순위 대로 정렬되어 있음
    System.out.println(priorityQueue);
    // [Student{name='홍길동', priority=1}, Student{name='임꺽정', priority=2}, Student{name='주몽', priority=5}, Student{name='세종', priority=9}]

LinkedList 클래스

  • LinkedList는 List 인터페이스와 Queue 인터페이스를 동시에 상속받고 있기 떄문에, 스택/큐로서도 응용이 가능하다.
  • 큐는 데이터를 꺼낼 때 항상 첫번 째 저장된 데이터를 삭제하므로 QrrayList와 같이 배열 기반의 컬렉션 클래스를 사용한다면, 데이터를 꺼낼때마다 빈 공간을 채우기 위해 데이터의 이동 & 복사가 발생하므로 비효율적이다.
    • 따라서 ArrayList보다 데이터의 추가/삭제가 용이한 LinkedList로 구현하는 것이 적합하다.

Deque 인터페이스

  • 양쪽으로 넣고 빼는 것이 가능한 큐를 말한다.
  • 스택과 큐를 하나로 합쳐놓은 것과 같으며 스택으로 사용할 수도 있고, 큐로 사용할 수도 있다.
  • Deque의 조상은 Queue이며, 구현체로 ArrayDequeLinkedList 등이 있다.

ArrayDeque 클래스

  • 스택으로 사용할 때 Stack 클래스보다 빠르며, 대기열로 사용할 때는 LinkedList보다 빠르다.
  • 사이즈에 제한이 없다.
  • null은 요소는 저장되지 않는다.

Set 인터페이스

  • 중복을 허용하지 않는 자료구조를 표현하는 인터페이스
  • 순서 자체가 없으므로 인덱스로 객체를 가져오는 get(index) 메서드가 존재하지 않는다.

HashSet 클래스

  • 배열과 연결 노드를 결합한 자료구조 형태
  • 가장 빠른 임의 검색 접근 속도를 가진다.
  • 추가, 삭제, 검색, 접근성 모두 뛰어나다.
  • 순서를 전혀 예측할 수 없다.

LinkedHashSet 클래스

  • 순서를 가지는 Set 자료
  • 중복을 제거하는 동시에 저장한 순서를 유지하고 싶으면, HashSet 대신 LinkedHashSet을 사용하면 된다.

TreeSet 클래스

  • 이진 검색 트리 자료구조의 형태로 데이터를 저장
  • 중복을 허용하지 않고, 순서를 가지지 않는다.
  • 데이터를 정렬하여 저장한다.
  • 정렬, 검색, 범위 검색에 높은 성능을 뽐낸다.

Map 인터페이스

  • KeyValue를 가지는 자료구조
  • 값(value)은 중복되서 저장될수 있지만, 키(key)는 해당 Map에서 고유해야만 한다.
  • 만일 기존에 저장된 데이터와 중복된 키와 값을 저장하면 기존의 값은 없어지고 마지막에 저장된 값이 남게 된다.
  • 저장 순서가 유지 되지 않는다
  • 모든 key들에 대한 정보를 읽어들일 수 있는 Set을 반환하는 keySet()메소드를 가지고 있다.
  • values는 중복을 허용하기 때문에 Collection 타입으로 반환한다.

Map.Entry 인터페이스

  • Map.Entry 인터페이스는 Map 인터페이스 안에 있는 내부 인터페이스이다.
  • Map 에 저장되는 key - value 쌍의 Node 내부 클래스가 이를 구현하고 있다.
  • Map 자료구조를 보다 객체지향적인 설계를 하도록 유도하기 위한 것이다.
Map<String, Integer> map = new HashMap<>();
map.put("a", 1);
map.put("b", 2);
map.put("c", 3);
 
// Map.Entry 인터페이스를 구현하고 있는 Key-Value 쌍을 가지고 있는 HashMap의 Node 객체들의 Set 집합을 반환
Set<Map.Entry<String, Integer>> entry = map.entrySet();
 
System.out.println(entry); // [1=a, 2=b, 3=c]
 
// Set을 순회하면서 Map.Entry를 구현한 Node 객체에서 key와 value를 얻어 출력
for (Map.Entry<String, Integer> e : entry) {
    System.out.printf("{ %s : %d }\n", e.getKey(), e.getValue());
}

HashMap 클래스

  • 중복을 허용하지 않고 순서를 보장하지 않는다.
  • 키와 값으로 null이 허용된다.
  • 추가, 삭제, 검색, 접근성이 모두 뛰어나다.
  • 비동기로 작동하기 때문에 멀티 쓰레드 환경에서는 ==ConcurrentHashMap==을 사용한다.

LinkedHashMap 클래스

  • HashMap을 상속하지만, Entry들이 연결 리스트를 구성하여 데이터의 순서를 보장한다.

TreeMap 클래스

  • 이진 검색 트리의 형태로 키와 값의 쌍으로 이루어진 데이터를 저장
  • TreeMapSortedMap 인터페이스를 구현하고 있어 ==Key 값을 기준으로 정렬==되는 특징을 가지고 있다.
  • 정렬된 순서로 키/값 쌍을 저장하므로 빠른 검색이 가능하다.
  • 단, 키와 값을 저장하는 동시에 정렬을 행하기 때문에 저장시간이 다소 오래 걸린다.
  • 정렬되는 순서느 숫자 → 알파벳 대문자 → 알파벳 소문자 → 한글 순이다.

인파 (2023.01) Java Collections Framework 종류 💯총정리