Java의 Collections는 데이터를 효율적으로 저장, 검색, 조작할 수 있도록 도와주는 자료구조 클래스와 인터페이스들의 집합이다.

자바에서 많이 사용하는 List, Set, Map, Queue 등이 여기에 속한다.

 


1. Collections(Collections Framework)란?

  • Java.util 패키지에 포함되어 있다.
  • 데이터를 저장, 정렬, 검색, 수정 등의 작업을 효율적으로 할 수 있도록 설계된 인터페이스 + 구현 클래스들의 모음이야.

2. 주요 인터페이스와 구현체


 

인터페이스 특징 주요 구현 클래스
List 순서 O, 중복 허용 ArrayList, LinkedList, Vector
Set 순서 X, 중복 X HashSet, LinkedHashSet, TreeSet
Map 키-값 쌍 저장, 키 중복 X HashMap, TreeMap, LinkedHashMap
Queue FIFO 구조 LinkedList, PriorityQueue

 


3. Collections 클래스의 주요 메서드 정리

 

메서드 설명
sort(List<T> list) 리스트를 오름차순 정렬 (T는 Comparable 구현체여야 함)
sort(List<T> list, Comparator<? super T> c) 지정한 비교자(Comparator) 기준으로 정렬
reverse(List<T> list) 리스트의 순서를 역순으로 변경
shuffle(List<T> list) 리스트 요소들의 순서를 무작위로 섞음
swap(List<T> list, int i, int j) 리스트에서 두 요소의 위치를 맞바꿈
max(Collection<? extends T> coll) 컬렉션에서 가장 큰 요소 반환
min(Collection<? extends T> coll) 컬렉션에서 가장 작은 요소 반환
binarySearch(List<? extends Comparable<? super T>> list, T key) 정렬된 리스트에서 이진 탐색으로 요소 위치 찾기
fill(List<? super T> list, T obj) 리스트의 모든 요소를 지정한 값으로 채움
copy(List<? super T> dest, List<? extends T> src) src 리스트 내용을 dest 리스트에 복사
replaceAll(List<T> list, T oldVal, T newVal) 리스트에서 특정 값을 찾아 새 값으로 모두 바꿈
frequency(Collection<?> c, Object o) 컬렉션에서 특정 객체가 몇 번 나오는지 카운트
disjoint(Collection<?> c1, Collection<?> c2) 두 컬렉션이 서로 겹치는 요소가 없는지 확인

간단한 예시

import java.util.*;

public class CollectionsExample {
    public static void main(String[] args) {
        List<Integer> numbers = new ArrayList<>(Arrays.asList(4, 2, 9, 1, 5));

        Collections.sort(numbers);  // [1, 2, 4, 5, 9]
        Collections.reverse(numbers);  // [9, 5, 4, 2, 1]
        Collections.shuffle(numbers);  // 무작위 섞기
        Collections.swap(numbers, 0, 1);  // 첫 번째와 두 번째 요소 교환

        int max = Collections.max(numbers);
        int min = Collections.min(numbers);
        int freq = Collections.frequency(numbers, 4);

        System.out.println("Max: " + max);
        System.out.println("Min: " + min);
        System.out.println("4의 개수: " + freq);
    }
}

 

 


Collections에 대해 간단하게 알아봤으니 이제는 Arrays에 대해 알아보겠다.

1. Arrays(java.util.Arrays) 클래스란?

  • 배열 전용 유틸리티 클래스 혹은 메서드 모음 (정렬, 복사, 비교 등)
  • 모든 메서드는 static(정적) → 객체 생성 없이 바로 사용 가능
  • java.util 패키지에 포함되어 있다.

2. 자주 사용하는 메서드

 

메서드 설명
Arrays.toString(array) 배열 내용을 문자열로 변환
Arrays.sort(array) 배열 정렬 (오름차순)
Arrays.copyOf(array, newLength) 배열을 복사하면서 크기 변경 가능
Arrays.equals(arr1, arr2) 두 배열의 내용이 같은지 비교
Arrays.fill(array, value) 배열을 하나의 값으로 모두 채움
Arrays.binarySearch(array, key) 정렬된 배열에서 이진 탐색 수행
Arrays.asList(array) 배열을 리스트로 변환 (단, 고정 크기)
Arrays.deepToString(array) 다차원 배열을 문자열로 변환
Arrays.deepEquals(arr1, arr2) 다차원 배열 내용 비교

3. 예시 코드

import java.util.Arrays;

public class ArraysExample {
    public static void main(String[] args) {
        int[] arr = {3, 5, 1, 2};

        Arrays.sort(arr); // 정렬
        System.out.println(Arrays.toString(arr)); // [1, 2, 3, 5]

        int[] copied = Arrays.copyOf(arr, 6); // 크기 6짜리로 복사
        System.out.println(Arrays.toString(copied)); // [1, 2, 3, 5, 0, 0]

        Arrays.fill(copied, 4); // 모든 요소를 4로 채움
        System.out.println(Arrays.toString(copied)); // [4, 4, 4, 4, 4, 4]

        int index = Arrays.binarySearch(arr, 3);
        System.out.println("3의 인덱스: " + index); // 2

        Integer[] nums = {10, 20, 30};
        System.out.println(Arrays.asList(nums)); // [10, 20, 30]
    }
}

 

 


 

Arrays와 Collections 차이

똑같이 java.util에 포함되어 있는 자료구조를 다루는 클래스들이지만

Arrays는 Collections에 존재하는 클래스가 아니다.

 

이는 둘이 다루는 자료구조의 차이 때문이다.

 

 

항목 Arrays(배열) Collections (ArrayList, HashSet 등)
크기 고정 가변
요소 추가/삭제 불가능 가능
저장 구조 배열 기반 다양한 구조 (배열, 연결리스트, 해시 등)
유연성 낮음 높음

 

 

Arrays가 다루는 자료구조인 배열은 크기가 고정되어 있으며 동일한 타입의 요소만 저장할 수 있고.

Collections가 다루는 자료구조들(List, Map, Queue, Set)은 크기가 가변적이며 제네릭스를 사용하여 다양한 타입의 요소를 저장할 수 있다는 차이가 있다.

 


 

다만 Arrays.asList()을 사용하여 배열을 리스트로 변환한 경우  Collections의 일부 메서드를 사용할 수 있다.

 

List<String> list = Arrays.asList("A", "B");
list.sort();  // Arrays의 sort가 아닌 Collections의 sort 이용
list.add("C"); // ❌ UnsupportedOperationException 발생
               // 예외가 발생하는 이유는 요소 추가/삭제 불가능한 배열을 가져와서 리스트의 형식으로 가져왔기 때문에
               // 자료형이 list로 바뀌었어도 요소 추가/삭제는 안된다고 한다.

 

 

 

이상으로 Arrays와 Collection에 대해 알아보았고 이 둘의 차이점에 대해서도 공부해 보았다.

블로그 이미지

Ahan

책, 영화, 게임! 인생의 활력 요소가 되는 취미들을 하자!

,

자바의 Queue는 FIFO(First-In-First-Out) 구조를 따르는 자료구조다.

즉, 먼저 추가된 요소가 먼저 제거되는 구조이다.

쉽게 기억하려면 맛집 대기열을 생각하면 된다. 먼저 온 순서대로 가게에 들어가서 먹고, 먼저 나온다라는 걸 이미지로 기억해 두면 편하다.

 

Queue는 인터페이스이며, 일반적으로 LinkedList, PriorityQueue, ArrayDeque 등으로 구현된다.

 

Queue의 상속 구조

java.util.Queue<E> extends java.util.Collection<E>
 

Queue는 Collection 인터페이스를 상속받아 만들어진 인터페이스이다. (그러므로 Queue<E> queue = new Queue<>(); 와 같은 식으로 구현은 못한다.)

그리고 Collection은 다시 Iterable을 상속한다.

 

전체 계층 구조:

java.lang.Iterable<E>
  └── java.util.Collection<E>
        └── java.util.Queue<E>

 


1. 기본 메서드

Queue 인터페이스는 java.util 패키지에 포함되어 있으며, 주요 메서드는 다음과 같다:

메서드 설명
add(E e) 큐에 요소를 추가. 공간이 없으면 예외 발생
offer(E e) 큐에 요소를 추가. 공간이 없으면 false 반환
remove() 큐의 헤드를 제거하고 반환. 큐가 비어있으면 예외 발생
poll() 큐의 헤드를 제거하고 반환. 큐가 비어있으면 null 반환
element() 큐의 헤드를 반환. 큐가 비어있으면 예외 발생
peek() 큐의 헤드를 반환. 큐가 비어있으면 null 반환

 

2. 예제 구현 (LinkedList 기반)

import java.util.LinkedList;
import java.util.Queue;

public class QueueExample {
    public static void main(String[] args) {
        Queue<String> queue = new LinkedList<>();

        queue.offer("Alpha");
        queue.offer("Bravo");
        queue.offer("Charlie");

        System.out.println("헤드 요소: " + queue.peek()); // Alpha

        while (!queue.isEmpty()) {
            System.out.println("제거: " + queue.poll());
        }
    }
}


// 출력
헤드 요소: Alpha
제거: Alpha
제거: Bravo
제거: Charlie
 

 


3. 자주 사용하는 구현체

 

구현체 특징
LinkedList 일반적인 FIFO 큐로 가장 많이 사용됨
PriorityQueue 요소들을 우선순위에 따라 정렬해서 처리
ArrayDeque 스택 또는 큐로 사용 가능. null 요소 허용 안 함

 

3-1. PriorityQueue

개요:

PriorityQueue는 우선순위가 높은 요소가 먼저 나오는 큐이다.

즉, 일반적인 FIFO 큐가 아니라, 요소를 넣은 순서보다 우선순위 기준(숫자 오름차순, 알파벳 순서 등)에 따라 순서가 결정됨.

특징:

  • 내부적으로 힙(heap) 구조로 되어 있음 (기본은 최소 힙)
  • Comparable 또는 Comparator를 통해 우선순위를 정할 수 있음
  • null 요소 저장 불가
  • 동기화 안 됨 (멀티스레드 환경에서는 PriorityBlockingQueue 사용)

기본 사용 예:

import java.util.PriorityQueue;

public class PriorityQueueExample {
    public static void main(String[] args) {
        PriorityQueue<Integer> pq = new PriorityQueue<>();

        pq.offer(30);
        pq.offer(10);
        pq.offer(20);

        while (!pq.isEmpty()) {
            System.out.println(pq.poll()); // 10, 20, 30
        }
    }
}
 

사용자 정의 우선순위 예:

PriorityQueue<String> pq = 
new PriorityQueue<>((a, b) -> b.length() - a.length()); // Comparator를 사용하여 사용자 정의 우선순위 지정

pq.offer("apple");
pq.offer("banana");
pq.offer("kiwi");

System.out.println(pq.poll()); // banana (가장 길이 김)

2. Deque (Double Ended Queue)

개요:

Deque는 양쪽 끝에서 삽입과 삭제가 가능한 큐다

Stack처럼도, Queue처럼도 사용할 수 있어서 유연성이 아주 높다.

대표 구현체: ArrayDeque, LinkedList

주의 : LinkedList가 이곳저곳에서 튀어나와서 헷갈릴 수 있다.

LinkedList는 특이하게 List와 Deque(Queue상속)를 둘 다 상속 받아 만들어진 클래스이다.

 

java.util.LinkedList<E> extends AbstractSequentialList<E>
                         implements List<E>, Deque<E>, Cloneable, Serializable

주요 메서드:


메서드 설명
addFirst(), offerFirst() 앞쪽에 요소 추가
addLast(), offerLast() 뒤쪽에 요소 추가
removeFirst(), pollFirst() 앞쪽 요소 제거
removeLast(), pollLast() 뒤쪽 요소 제거
peekFirst(), peekLast() 앞/뒤 요소 보기

 

예제:

import java.util.ArrayDeque;
import java.util.Deque;

public class DequeExample {
    public static void main(String[] args) {
        Deque<String> deque = new ArrayDeque<>();

        deque.offerFirst("Front");
        deque.offerLast("Back");

        System.out.println(deque.pollFirst()); // Front
        System.out.println(deque.pollLast());  // Back
    }
}

구현체  비교:

 

항목 PriorityQueue Deque (ArrayDeque)
구조 힙 기반 배열 기반
삽입 위치 자동 정렬됨 (우선순위) 앞뒤 둘 다
제거 방식 우선순위 높은 것 먼저 양쪽 다 가능
Null 허용 불가 불가
쓰임새 스케줄링, 경로 탐색 등 스택, 큐, 슬라이딩 윈도우
블로그 이미지

Ahan

책, 영화, 게임! 인생의 활력 요소가 되는 취미들을 하자!

,

https://hobbyatelier.tistory.com/97

 

Java) List란? (ArrayList, LinkedList, Vector 설명, 사용법, 예시)

자바의 List는 가장 자주 쓰이는 컬렉션 타입 중 하나로, 순서가 있는 데이터 집합을 다룰 때 사용된다.간단히 말하면 배열처럼 순서대로 데이터를 저장하고 관리할 수 있는 자료구조이다.  아

hobbyatelier.tistory.com

 

저번 글에서 List 클래스들의 구현체들에 대해 썼을 때, 

Stack에 대해서 잠시나마 썼었다.

Stack 대신에 Dequq(덱)이란 구현체를 쓰는 것을 추천했는데, 이는 잘못된 상속 설계로 인한 문제때문이다.

그럼에도 불구하고 Stack은 여러 코딩 테스트 문제에서 자주 다뤄지기에 Stack에 대해 써보려고 한다.

 

                List (인터페이스)               Stack의 상속 관계
                  ↑
   +--------------+--------------+
   |              |              |
ArrayList    LinkedList       Vector
                                |
                             Stack           - 스택은 Vector를 상속 받아 설계되었다.

 


 Stack(스택)이란?

 

자바의 Stack 클래스는 LIFO(Last-In-First-Out, 후입선출) 구조를 따르는 컬렉션 클래스이다.

즉, 가장 나중에 넣은 요소가 가장 먼저 나온다. 

예시로 택배 상하차를 생각하면 되는데, 트럭에 상자를 차곡차곡 쌓아 놓고 배달지에 도착하면 쌓아 놓은 상자를 위에서부터 내려놓는 이미지를 기억해 두면 편하다.

 

Java에서는 java.util.Stack 클래스로 제공되며, Vector 클래스를 상속받아 구현되어 있다.

1. 기본 구조

Stack<Type> stack = new Stack<>();

 

예시 :

Stack<Integer> stack = new Stack<>();  // Integer 스택

 

 

2. 주요 메서드


 

메서드 설명
push(E item) 스택의 top에 요소를 추가
pop() 스택의 top 요소를 제거하고 반환
peek() 스택의 top 요소를 제거하지 않고 반환
empty() 스택이 비어있는지 확인
search(Object o) 요소가 top으로부터 몇 번째인지 반환 (1부터 시작), 없으면 -1

 


3. 간단한 예제

import java.util.Stack;

public class StackExample {
    public static void main(String[] args) {
        Stack<String> stack = new Stack<>();

        stack.push("Alpha");
        stack.push("Bravo");
        stack.push("Charlie");

        System.out.println("Top element: " + stack.peek()); // Charlie
        System.out.println("Popped: " + stack.pop());       // Charlie
        System.out.println("Top now: " + stack.peek());     // Bravo
        System.out.println("Is empty? " + stack.empty());   // false
    }
}
 

 


3-1. 주의사항

  • Stack은 Vector를 상속받기 때문에 스레드-세이프(Thread-safe) 하지만, 요즘은 더 나은 대안으로 Deque 인터페이스(예: ArrayDeque)를 사용한다.
  • 예: Deque<Integer> stack = new ArrayDeque<>();

5. Stack의 시간 복잡도

 

연산시간  복잡도 설명
push() O(1) 요소를 top에 추가
pop() O(1) top 요소를 제거하고 반환
peek() O(1) top 요소를 반환 (제거 X)
search() O(n) 특정 요소 탐색 (top부터 순차 검색)
  • 대부분의 기본 연산은 상수 시간 O(1) 으로 매우 빠름
  • 단, search()는 내부에서 순차 탐색을 하므로 최악의 경우 O(n)

6. 공간 복잡도

  • O(n)
    n개의 요소를 저장할 수 있는 스택이라면, 요소를 담기 위해 선형적인 공간이 필요함.
    (스택의 크기와 동일하게 메모리를 사용)

7. 스택이 사용되는 대표적인 상황들

7-1. 재귀 호출 시 호출 스택

  • 자바를 포함한 대부분의 언어에서 함수 호출은 스택에 쌓임
  • 깊은 재귀 함수에서 StackOverflowError 가 발생할 수도 있음

7-2. 괄호 유효성 검사

7-3. 중위 → 후위 표기법 변환 / 계산기 구현

  • 연산자 우선순위를 관리할 때 스택 사용

7-4. DFS (깊이 우선 탐색)

  • 재귀적으로 구현되지만, 명시적으로 스택으로 구현 가능

7-5. 되돌리기(Undo), 브라우저 뒤로 가기

  • 사용자 동작을 스택에 저장하고, pop 하며 이전 상태로 되돌리는 구조

7-6. 문자열 뒤집기

  • 한 문자씩 push 후 pop 하면 역순으로 출력됨

8. 정리 요약

 

항목 내용
시간 복잡도 대부분 O(1), 검색은 O(n)
공간 복잡도 O(n)
사용 사례 재귀, 괄호 검사, DFS, 되돌리기, 수식 계산 등
대체 자료구조 Deque (ArrayDeque) – 더 빠르고 유연함

 

블로그 이미지

Ahan

책, 영화, 게임! 인생의 활력 요소가 되는 취미들을 하자!

,

자바의 List는 가장 자주 쓰이는 컬렉션 타입 중 하나로, 순서가 있는 데이터 집합을 다룰 때 사용된다.

간단히 말하면 배열처럼 순서대로 데이터를 저장하고 관리할 수 있는 자료구조이다. 

 

아래에 주요 내용을 정리해 보았다.


List란?

  • List는 java.util 패키지에 속한 인터페이스. (List<Integer> list = new List<>(); 같이 초기화를 못한다.)
  • 중복된 요소를 허용하고, 순서대로 요소를 유지한다.
  • 인덱스를 사용해서 요소에 접근할 수 있어요 (list.get(0) 같은 식으로).

1. 주요 구현 클래스

 

클래스 이름 특징 요약
ArrayList 배열 기반, 빠른 검색, 느린 삽입/삭제
LinkedList 노드 기반, 삽입/삭제 빠름, 검색 느림
Vector 예전 스타일, 동기화 됨 (멀티스레드용)
Stack LIFO 구조, Vector를 상속함 (Stack의 문제때문에 Deque(덱) 사용을 권장함)

2. 자주 쓰는 메서드 간단 예시

List<String> list = new ArrayList<>();

list.add("Apple");         // 요소 추가
list.add("Banana");
list.add(1, "Orange");     // 인덱스에 삽입

String fruit = list.get(0); // 요소 읽기
list.set(0, "Peach");       // 요소 수정
list.remove("Banana");      // 값으로 삭제
list.remove(0);             // 인덱스로 삭제

int size = list.size();     // 크기 확인
boolean hasOrange = list.contains("Orange"); // 포함 여부 확인
list.clear();               // 전체 삭제

3. for-each 루프 예시

for (String item : list) {
    System.out.println(item);
}

4. 제네릭(Generic)을 이용한 타입 안전성

List<String>, List<Integer> 처럼 사용해서 타입 안정성을 확보할 수 있다.

덕분에 형 변환 없이 사용할 수 있다.

 

 


각 구현체의 차이점은 무엇일까?

ArrayList, LinkedList, Vector는 모두 List 인터페이스를 구현한 클래스들이고, 비슷해 보이지만

동작 방식이나 성능, 사용 목적이 조금씩 다르다.

 

아래에 각각의 차이점을 정리해 보았다.


1. 차이점 요약


 

특성 ArrayList LinkedList Vector
내부 구조 배열 기반 이중 연결 리스트 기반 배열 기반
검색 속도 빠름 (index 접근 O(1)) 느림 (순차 탐색 O(n)) 빠름 (index 접근 O(1))
삽입/삭제 느림 (중간에선 O(n)) 빠름 (중간 삽입/삭제 O(1)) 느림 (동기화로 인해)
동기화 ❌ 비동기 ❌ 비동기 ✅ 동기화 (멀티스레드에 안전)
사용 시기 읽기 중심 삽입/삭제 중심 멀티스레드 환경에서 필요할 때

 


2. 언제 어떻게 써야 할까?

차이점은 알았지만 결국 언제 어떤 걸 써야 할지 모르면 힘들다.

각 List 구현체 (ArrayList, LinkedList, Vector)는 내부 구조와 동작 방식이 다르기 때문에,

상황에 따라 잘 골라 써야 성능이나 안정성 면에서 이득을 볼 수 있다.

 

 다음과 같은 상황에 쓰면 편할것이다.

상황 추천 클래스
읽기/검색이 많고 동기화 필요 없음 ArrayList
삽입/삭제가 빈번함 (특히 중간 위치) LinkedList
멀티스레드 환경에서 사용 필요 Vector (하지만 Collections.synchronizedList() 또는 CopyOnWriteArrayList 추천됨)

 

 

2-1. ArrayList – 읽기/탐색 위주 데이터에 적합

특징

  • 내부 구조: 배열 기반
  • 장점: 인덱스로 빠르게 접근 가능 (get() 속도 빠름)
  • 단점: 중간 삽입/삭제 시 느림 (뒤 요소 전부 밀어야 함)

사용 예시

 

상황 이유
게시판 글 목록 인덱스로 바로 접근해서 출력
상품 리스트 빠른 탐색/정렬이 중요
유저 순위표 변경이 적고 조회가 잦음
페이징 처리 인덱스 기반 분할 처리 용이

2- 2. LinkedList – 삽입/삭제가 잦거나 큐/스택처럼 동작할 때 적합

특징

  • 내부 구조: 이중 연결 리스트
  • 장점: 앞뒤 삽입/삭제 빠름 (addFirst, removeLast 등)
  • 단점: 인덱스로 접근 시 느림 (한 칸씩 따라가야 함)

사용 예시


 

상황 이유
명령어 실행 히스토리 (Undo/Redo) 끝에서 삽입/삭제가 빠름
게임 처리 순서 (작업 큐) FIFO 구조
실시간 알림 대기열 빠른 순차 처리 필요
음악 재생 대기열 재생 순서 수정/제거가 잦음
 

2-3. Vector – 멀티스레드 환경에서 쓰기 안정성을 보장할 때 사용

특징

  • 내부 구조: 배열 기반 (ArrayList와 유사)
  • 장점: 동기화 되어 있어 멀티스레드에서 안전
  • 단점: 단일 스레드 환경에서는 느림 (성능 손해)

사용 예시

이유 상황 이유
채팅 메시지 저장 여러 유저의 입력을 동시에 받음
실시간 로그 기록 다중 스레드에서 기록 발생 가능
동기화된 리스트 필요 데이터를 안전하게 공유해야 함
 

참고: 최신 자바에서는 Vector보다
Collections.synchronizedList(new ArrayList<>())
또는 CopyOnWriteArrayList를 더 많이 사용한다고 함.


2-4 정리: 상황별 추천 표

 

상황추천 구현체 이유
조회/정렬이 많은 경우 ArrayList 빠른 인덱스 접근
삽입/삭제가 잦은 경우 LinkedList 앞뒤 수정이 빠름
멀티스레드 환경 Vector (또는 동기화된 리스트) 동기화 제공
FIFO 큐 처리 LinkedList Queue 인터페이스 구현
스택처럼 사용 LinkedList Deque 기능도 있음

 

 


3. 자주 쓰는 메서드 정리

ArrayList, LinkedList, Vector 세개의 구현체에서 공통으로 사용할 수 있는 메서드를 정리해 보았다.

add(E e);            // 요소 추가
add(int index, E e); // 특정 위치에 삽입
get(int index);      // 인덱스로 요소 가져오기
set(int index, E e); // 인덱스의 요소 수정
remove(int index);   // 인덱스의 요소 제거
remove(Object o);    // 값으로 요소 제거
contains(Object o);  // 포함 여부 확인
clear();             // 전체 삭제
size();              // 리스트 크기 확인
isEmpty();           // 비어있는지 확인

 

4. 간단한 구현 예제

1. ArrayList 구현

import java.util.ArrayList;

public class ArrayListExample {
    public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<>();
        list.add("Java");
        list.add("Python");
        list.add("C++");

        for (String lang : list) {
            System.out.println(lang);
        }
    }
}

 

 

2. LinkedList 구현

import java.util.LinkedList;

public class LinkedListExample {
    public static void main(String[] args) {
        LinkedList<String> queue = new LinkedList<>();
        queue.add("Task 1");
        queue.add("Task 2");
        queue.addFirst("Urgent Task");

        while (!queue.isEmpty()) {
            System.out.println(queue.removeFirst());
        }
    }
}

 

 

3. Vector 구현

import java.util.Vector;

public class VectorExample {
    public static void main(String[] args) {
        Vector<Integer> numbers = new Vector<>();
        numbers.add(10);
        numbers.add(20);
        numbers.add(30);

        for (int num : numbers) {
            System.out.println(num);
        }
    }
}

 

블로그 이미지

Ahan

책, 영화, 게임! 인생의 활력 요소가 되는 취미들을 하자!

,

https://hobbyatelier.tistory.com/94

 

Java) Map 자료구조 간단 설명

Map은 키-값(key-value) 쌍으로 데이터를 저장하는 자료구조입니다. 간단히 말하면, 특정 키를 이용해 원하는 값을 빠르게 찾을 수 있게 해주는 구조이다.1. 기본 개념인터페이스 이름: java.util.Map대

hobbyatelier.tistory.com

 

이전 게시글에서는 Map 자료구조에 대해서 썼었다.

 

이번에는 Map 인터페이스를 구현한 대표적인 3가지 구현체에 대해 써보겠다.


1. 자바에서 제공하는 주요 Map 구현체들

  1. HashMap
    • 가장 일반적으로 쓰이는 Map.
    • 키 순서를 보장하지 않음.
    • null 키와 null 값을 허용.
  2. LinkedHashMap
    • HashMap의 확장.
    • 입력 순서를 유지함.
    • 순회 순서가 예측 가능.
  3. TreeMap
    • 정렬된 Map.
    • 키의 자연 순서나 Comparator를 기준으로 정렬.
    • 성능은 HashMap보다 느리지만 정렬이 필요할 때 유용.

 

2. 자주 쓰는 Map 3종 비교

항목 HashMap LinkedHashMap TreeMap
정렬/순서 없음 입력 순서 유지 자동 정렬 (오름차순)
시간 복잡도 O(1) (평균) O(1) (평균) O(log n)
기반 구조 해시 테이블 해시 테이블 + 연결 리스트 레드-블랙 트리
null 키/값 허용 허용 허용 키는 불가, 값은 허용
사용 예시 빠른 조회 순서를 중요시할 때 정렬된 맵 필요할 때

 


3.언제 어떤 걸 써야 할까?

  • HashMap
    → 기본 Map으로 거의 모든 경우에 사용 가능. 성능도 좋고 가장 많이 쓰임.
    → 단, 순서에 대한 보장이 전혀 없다는 걸 기억.
  • LinkedHashMap
    → 반복 순서가 중요할 때 (예: 캐시 구현, 최근 입력 순서대로 출력 등).
    → 입력 순서를 그대로 유지하므로 디버깅할 때도 보기 편함.
  • TreeMap
    → 키를 정렬된 상태로 유지해야 할 때.
    → ex) 사전식 정렬, 범위 검색 (subMap, tailMap 등) 기능이 유용함.

4. Map의 대표적인 3가지 구현체 사용법

HashMap, LinkedHashMap, TreeMap은 모두 Map 인터페이스를 구현하고 있어서 기본적인 함수들은 거의 동일함.

하지만 TreeMap은 정렬과 탐색 관련된 기능이 추가로 좀 더 있고, LinkedHashMap은 순서 유지와 관련된 특징이 있다.


5. 공통적으로 제공되는 주요 Map 인터페이스 메서드

(HashMap, LinkedHashMap, TreeMap 모두 사용 가능)

메서드 설명

put(K key, V value) 키-값 쌍 추가 (또는 덮어쓰기)
get(Object key) 키로 값 조회
remove(Object key) 키로 항목 제거
containsKey(Object key) 해당 키가 존재하는지 확인
containsValue(Object value) 해당 값이 존재하는지 확인
size() 맵에 있는 항목 수
isEmpty() 맵이 비어 있는지 확인
clear() 모든 항목 제거
keySet() 키들의 Set 반환
values() 값들의 Collection 반환
entrySet() Map.Entry 객체들의 Set 반환

6. LinkedHashMap 특유의 메서드

메서드 설명

LinkedHashMap(int initialCapacity, float loadFactor, boolean accessOrder) TreeMap 가 true일 경우, 최근 접근 순서로 정렬
→ 사용 예시: LRU 캐시 구현 가능  

 


7. TreeMap 특유의 메서드

(NavigableMap, SortedMap 인터페이스도 구현함)

메서드 설명

firstKey() / lastKey() 가장 작은 / 큰 키 반환
higherKey(K key) 주어진 키보다 큰 가장 작은 키
lowerKey(K key) 주어진 키보다 작은 가장 큰 키
ceilingKey(K key) 주어진 키 이상인 가장 작은 키
floorKey(K key) 주어진 키 이하인 가장 큰 키
subMap(K fromKey, K toKey) 키 범위로 부분 맵 반환
descendingMap() 내림차순 정렬된 맵 반환

8. 구현 예시 :

1) HashMap 

Map<String, Integer> map = new HashMap<>();
map.put("apple", 1);
map.put("banana", 2);
System.out.println(map.get("apple"));  // 1
System.out.println(map.containsKey("banana"));  // true

 

 

2) TreeMap

TreeMap<String, Integer> treeMap = new TreeMap<>();
treeMap.put("c", 3);
treeMap.put("a", 1);
treeMap.put("b", 2);
System.out.println(treeMap.firstKey());  // a가 순서상 가장 앞임 a,b,c ...
System.out.println(treeMap.subMap("a", "c"));  // {a=1, b=2}

 

3) LinkedHashMap

 - 입력 순서 유지

import java.util.LinkedHashMap;
import java.util.Map;

public class LinkedHashMapExample {
    public static void main(String[] args) {
        Map<String, Integer> linkedMap = new LinkedHashMap<>();

        linkedMap.put("apple", 10);
        linkedMap.put("banana", 20);
        linkedMap.put("cherry", 30);

        for (Map.Entry<String, Integer> entry : linkedMap.entrySet()) {
            System.out.println(entry.getKey() + " = " + entry.getValue());
        }
    }
}


// 출력 결과 
apple = 10
banana = 20
cherry = 30

 

- 접근 순서 유지

import java.util.LinkedHashMap;
import java.util.Map;

public class LRUExample {
    public static void main(String[] args) {
        // accessOrder = true → 최근 사용된 순서대로 정렬
        Map<String, String> lruMap = new LinkedHashMap<>(16, 0.75f, true);

        lruMap.put("A", "Apple");
        lruMap.put("B", "Banana");
        lruMap.put("C", "Cherry");

        // "A"에 접근
        lruMap.get("A");

        for (Map.Entry<String, String> entry : lruMap.entrySet()) {
            System.out.println(entry.getKey() + " = " + entry.getValue());
        }
    }
}

// 출력 결과
B = Banana
C = Cherry
A = Apple  // A에 접근했기 때문에 가장 마지막에 출력됨.
블로그 이미지

Ahan

책, 영화, 게임! 인생의 활력 요소가 되는 취미들을 하자!

,

Map은 키-값(key-value) 쌍으로 데이터를 저장하는 자료구조입니다. 간단히 말하면, 특정 키를 이용해 원하는 값을 빠르게 찾을 수 있게 해주는 구조이다.


1. 기본 개념

  • 인터페이스 이름: java.util.Map
  • 대표적인 구현체:
    • HashMap (가장 많이 사용됨)
    • TreeMap (정렬된 순서 유지)
    • LinkedHashMap (입력 순서 유지)
    • ConcurrentHashMap (동시성 지원)

2. 주요 특징

  • Key는 중복될 수 없음 (Set처럼 유일해야 함)
  • Value는 중복 가능
  • 빠른 검색, 삽입, 삭제를 위해 주로 사용

3. 사용 예시 (HashMap 기준)

import java.util.HashMap;
import java.util.Map;

public class MapExample {
    public static void main(String[] args) {
        Map<String, Integer> scoreMap = new HashMap<>();

        // 값 추가
        scoreMap.put("Alice", 90);
        scoreMap.put("Bob", 85);
        scoreMap.put("Charlie", 95);

        // 값 가져오기
        System.out.println(scoreMap.get("Alice")); // 90

        // 값 수정
        scoreMap.put("Bob", 88);

        // 키 존재 여부 확인
        System.out.println(scoreMap.containsKey("Charlie")); // true

        // 전체 순회
        for (String key : scoreMap.keySet()) {
            System.out.println(key + ": " + scoreMap.get(key));
        }

        // 제거
        scoreMap.remove("Alice");
    }
}

4. 메서드 요약

메서드 설명

put(key, value) 값 추가 또는 수정
get(key) 키에 해당하는 값 가져오기
remove(key) 해당 키의 항목 제거
containsKey(key) 해당 키 존재 여부 확인
containsValue(value) 해당 값 존재 여부 확인
keySet() 모든 키 가져오기 (Set 반환)
values() 모든 값 가져오기 (Collection 반환)
entrySet() key-value 쌍을 모두 가져오기 (Set<Map.Entry> 반환)

 

블로그 이미지

Ahan

책, 영화, 게임! 인생의 활력 요소가 되는 취미들을 하자!

,