프로그래밍/Java

[Java] 컬렉션 프레임워크란?

JBisCode 2023. 7. 28. 23:59



🔳 JAVA 컬렉션 프레임워크란? Collection Framework

컬렉션은 다수의 요소를 하나의 그룹으로 묶어 효율적으로 저장하고, 관리할 수 있는 기능을 제공하는 일종의 컨테이너다. 배열은 크기가 고정되어있지만, 컬렉션 프레임워크는 가변적인 크기를 갖는 특징을 가지고있다. 데이터 삽입, 탐색, 정렬등 다양한 API를 제공한다. 이를 활용하면 복잡한 데이터 처리를 간단하고 효율적으로 할 수 있다!

▶︎ 컬렉션 프레임워크 장점

  • List, Queus, Set, Map 등의 인터페이스를 제공하고 여러가지 API를 이용가능하다.
  • 가변적인 공간을 제공한다. (데이터의 크기에 따라 유연하게 대처가능)
  • 자료구조, 알고리즘을 구현하기 위한 코드를 직접 작성할 필요 없이, 준비된 클래스를 이용하여 해결할 수 있다.

▶︎ 컬렉션 프레임워크 인터페이스의 종류 및 특징

인터페이스설명구현 클래스
List<E>순서가 있는 데이터의 집합으로, 데이터의 중복을 허용함.Vector, ArrayList, LinkedList, Stack, Queue
Set<E>순서가 없는 데이터의 집합으로, 데이터의 중복을 허용하지 않음.HashSet, TreeSet
Map<K, V>키와 값의 한 쌍으로 이루어지는 데이터의 집합으로, 순서가 없음. 이때 키는 중복을 허용하지 않지만, 값은 중복될 수 있음.HashMap, TreeMap, Hashtable, Properties

▶︎ 컬렉션 프레임워크 시각화자료



 List 인터페이스

  • List는 순서가 있는 데이터의 집합이고, 데이터를 중복해서 저장할 수 있다.
  • 데이터를 인덱스로 관리하며, 데이터의 추가, 조회, 수정, 삭제 등이 가능하다.
  • ArrayList, LinkedList가 대표적인 클래스들이다.

✔️ ArrayList

ArrayList는 데이터의 조회가 빠르지만, 삽입과 삭제에는 비용이 크게 작용하는 단점이 있다.

add(), get(), set(), remove(), contains(), indexOf(), size()

import java.util.ArrayList

ArrayList<Integer> list1 = new ArrayList<>();

	list1.add(1); //[1]
	list1.add(2); //[1,2]
	list1.add(3); //[1,2,3]
	
	list1.remove(Integer.valueOf(2));  //[1,3]
	
	list1.add(index, value);  //[10,1,3]
	
	System.out.println(list1.get(2)); // 3 데이터 조회
	list1.set(index, 내용);  // 데이터 수정
	list1.remove(index);  //데이터 삭제
	
	System.out.println(list1.size()); // 3  길이확인
	System.out.println(list1.contains(1)); //true
	System.out.println(list1.indexOf(0));  // 10


✔️ LinkedList

LinkedList는 데이터의 삽입과 삭제가 빠르고, 메모리를 효율적으로 사용가능하다. 대신 데이터의 조회가 느리다. 자주 변하는 데이터를 다루는 데에 유용하다.

add(), addFirst(), addLast()remove(), removeFirst(), removeLast()get(), getFirst(), getLast()size(), isEmpty(), clear(), contains(), indexOf()

import java.util.LinkedList;

LinkedList<Integer> list1 = new LinkedList<>();

	list1.add(1); //[1]
	list1.add(2); //[1,2]
	list1.add(3); //[1,2,3]
	
	list1.addFirst(10); //[10,1,2,3]
	list1.addLast(20); //[10,1,2,3,20]
	
	list1.remove(Integer.valueOf(1)); //[10,2,3,20]
	
	list1.add(0,10); //[10,10,2,3,20]
	
	list1.removeFirst(); //[10,2,3,20]
	list1.removeLast(); //[10,2,3]
	
	System.out.println(list1.size()); // 3
	System.out.println(list1.contains(1));//false
	System.out.println(list1.indexOf(1)); // -1  존재하지않으면 -1표시


✔️ Stack

Stack은 후입선출(LIFO)을 따르는 자료구조이다. List 인터페이스를 구현한 클래스는 아니지만 사용할 수 있다. Stack은 Vector에서 파생된 클래스이다. 삽입, 추출을 push,pop으로 한다. 후입선출의 특성으로 최근에 수행한 작업을 되돌리는 작업에 사용.

push() = 맨위에 새로운 값을 추가한다. 추가할수없으면 exception을 출력한다. add()도 사용가능하지만 add는 List에서 제공하며 boolean을 나타낸다. Stack에선 push를 사용하자. → pop() = Stack맨위에 있는 요소를 제거한다. (동시에 출력도 할수있다.) → peek() = Stack 맨위에 있는 요소를 출력하지만 제거하지 않는다. → isEmpty() = Stack이 비어있는지 확인한다. empty()도 같은동작으로 사용가능하지만 isEmpty()를 사용하자. → search() = Stack에 있는 값이 존재한다면 몇번째 차례인지 알려준다. 여기서는 인덱스가 아니라 순서를 나타낸다. 만약 동일한 값이 존재한다면 가까운 순번의 순번을 알려준다. 없으면 -1 반환. → contains() = Stack에 값이 있는지 없는지 확인하고 boolean으로 반환한다. → size()

import java.util.Stack;

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

	// 데이터 추가 (push)
	stack.push("사과");
	stack.push("바나나");
	stack.push("딸기");
	
	// 최상단 데이터 조회 (pop 하지 않음)
	System.out.println(stack.peek()); // 결과: "딸기"
	
	// 데이터 추출 (pop)
	String topFruit = stack.pop(); // 최상단 데이터 추출
	System.out.println(topFruit); // 결과: "딸기"
	
	// 전체 데이터 출력 (pop으로 인해 데이터가 추출됨)
	while (!stack.isEmpty()) {
	    System.out.println(stack.pop());



 Queue 인터페이스

Queue는 선입선출(FIFO)을 따르는 자료구조이다. 역시 List인터페이스를 구현한 클래스는 아니다. Queue는 단순한 인터페이스라고 볼 수 있고, 이를 구현하는 클래스는 PriorityQueue(우선순위), ArrayDeque(배열 양방향), LinkedList(연결리스트) 이렇게 세가지가 있다.

offer() = 새로운 요소를 추가할때 사용한다. Queue를 사용할땐 offer를 쓰도록하자. List에 있는 add()도 사용가능하지만 되도록 쓰지말자.add()는 한계발생시 Exception을 출력, offer는 발생 X → poll() = 큐의 첫 번째 요소를 제거하면서 출력한다. remove()는 제거할데이터없으면 Exception을 출력하고 poll은 null을 리턴한다. → peek() = 큐의 첫번째 요소를 제거하지않고 출력한다. element()와 비슷하다. 오류시 element는 Exception peek는 null을 return → clear() = 큐를 비운다. → size()

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

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

    // 데이터 추가 (offer)
    queue.offer("사과");
    queue.offer("바나나");
    queue.offer("딸기");

    // 첫 번째 데이터 조회 (poll 하지 않음)
    System.out.println(queue.peek()); // 결과: "사과"

    // 데이터 추출 (poll)
    String firstFruit = queue.poll(); // 첫 번째 데이터 추출
    System.out.println(firstFruit); // 결과: "사과"

    // 전체 데이터 출력 (poll로 인해 데이터가 추출됨)
    while (!queue.isEmpty()) {
        System.out.println(queue.poll());
    }
}
}



 Set 인터페이스

  • 기본적으로 순서를 유지하지 않는 데이터의 조합
  • 데이터 중복을 허용하지 않는다.
  • 기본적으로 List계열은 index로 관리하기 때문에 add()와 같은 메소드를 쓰면 순서대로 저장된다, Queue또한 PriorityQueue를 제외하고는 기본적으로 입력한 순서대로 연결된다. 하지만 Set는 일반적으로 입력받는 순서와 상관없이 데이터를 집합시키기 때문에 입력받은 순서를 보장하지 않는다.

✔️ HashSet

무작위로 값을 담는 Set이다. 중복은 역시 허용하지 않으며 효율이 좋다. 삽입, 삭제, 색인이 매우 빠른 컬렉션 중 하나 내부적으로는 HashMap을 사용한다.

add() = 지정된 요소가 없을경우 추가하고, 같은 값이 존재하는경우 false를 반환 remove()= 객체가 집합에 존재하는경우 해당요소를 제거한다. → contains() = 요소가 집합에 존재하는지 확인 → isEmpty() = 집합이 비어있을경우 true 안비었을때 false반환 → size() = 집합 요소 개수 → clear() = 집합의 모든 요소를 제거 → iterator() = Set의 요소들을 순회하는데 사용된다. default 오름차순 // Set에서는 index가 없기때문에 get()을 사용할 수 없다. 그래서 itrerator을 사용해야함

✔️ LinkedHashSet

LinkedHashSet은 일반적인 Set와 다르게 넣은 순서대로 값을 담는 세트이다. (순서를 가진다.) 내부적으로 LinkedHashMap을 사용한다.

✔️ TreeSet

HashSet과 동일하지만 이용하는 관점에서 차이가 있다. 데이터를 오름차순으로 정렬한다.

TreeSet<Integer> tSet = new TreeSet<>();

	tSet.add(1); //[1]
	tSet.add(2); //[1,2]
	tSet.add(3); //[1,2,3]
	
	tSet.add(10); //[1,2,3,10]
	tSet.add(5); //[1,2,3,5,10]
	
	System.out.println(tSet.first()); //1
	System.out.println(tSet.last()); //10
	System.out.println(tSet.lower(10)); // 5
	System.out.println(tSet.higher(2)); // 3



✅ Map 인터페이스

List와 Set랑 다르게 추가할때 put()을 이용해서 key,”value”값을 추가한다.

put(key,value) = 데이터를 저장한다, 같은 key값으로 데이터를 넣으면 값이 수정된다. key는 중복될수없지만 value는 중복되는 값을 가질 수 있다. → remove(key) = 데이터를 삭제한다. 존재하지 않는 key를 삭제하면 Null을 리턴한다. → get(key) = 데이터를 읽어온다. 존재하지 않는 key는 null 리턴 → keySet() = key값을 전부 가져온다. → entrySet() = key값과 value값을 전부 가져온다. → values() = value값을 전부 가져온다. → iterator()

✔️ HashMap

  • 데이터의 순서를 보장하지 않으며 순서와 상관없이 빨리 값을 찾으려고 할때 효율적이다.

✔️ TreeMap

  • 키의 기본정렬기준은 오름차순이고, 사용자 정의 정렬 기준을 설정할 수 있다.
  • 데이터의 추가와 조회에는 시간이 좀 더 걸리지만, 정렬된 상태로 데이터를 유지 할 때 유리하다.

TreeMap<Integer,String> tMap = new TreeMap<>();
	tMap.put(10, "kiwi"); //{5=apple}
	tMap.put(5, "apple"); //{5=apple, 10=kiwi}
	tMap.put(15, "mango"); //{5=apple, 10=kiwi, 15=mango}
	
	System.out.println(tMap); //{5=apple, 10=kiwi, 15=mango}
	
	System.out.println(tMap.firstEntry()); // 5=apple
	System.out.println(tMap.firstKey()); //5
	System.out.println(tMap.lastEntry()); // 15=mango
	System.out.println(tMap.lastKey()); // 15
	System.out.println(tMap.lowerEntry(10)); // 5=apple
	System.out.println(tMap.higherKey(10)); // 15