[Java] 컬렉션 프레임워크
✅ 컬렉션 프레임워크
- 여러가지 데이터를 메모리에서 쉽고 효과적으로 처리할 수 있는 표준화된 방법을 제공하는 클래스들의 집합
- 자료구조를 구현한 클래스의 모음
⭐ 자료구조
- 데이터를 효율적으로 관리할 수 있는 데이터 구조를 의미
- 데이터의 특성에 따라 체계적으로 구조화함
⭐ 알고리즘
- 어떤 문제를 풀기 위한 절차 및 방법
- 어떤 문제에 대해 입력을 넣으면 원하는 출력을 얻을 수 있도록 만드는 프로그래밍
List 인터페이스
- 순서가 있는 데이터들의 집합으로 데이터의 중복을 허용
- Vector, ArrayList, LinkedList, Stack, Queue
Set 인터페이스
- 순서가 없는 데이터 집합으로 데이터의 중복을 허용하지 않음
- HashSet, TreeSet
Map 인터페이스
- 키와 값을 한 쌍으로 이루어지는데 데이터의 집합으로 순서가 없고, 키는 중복으로 허용하지 않지만 값은 중복될 수 있음
- HashMap, TreeMap, HashTable, Properties
List - Vector
Vector
- 동적인 길이로 여러 데이터형을 저장하기 위해 사용
- 자바 1.0부터 존재하는 레거시 클래스
- 배열과 동이랗게 정수 인덱스를 이용하여 액세스 할 수 있음
- 동기화 되어 있으며 한번에 하나의 스레드만 벡터의 메소드를 호출 할 수 있음
실행 순서
⭐ 동기식
차례(순서)대로 처리
⭐ 비동기식
여러개의 프로그램을 동시에 처리하거나, 시간이 오래 걸리면 다음 문장으로 이동 후 다시 돌아가는 방식
벡터 생성
Vector<타입> 참조변수 = new Vector(요소의 개수);
- <타입>을 작성하지 않으면 여러 데이터형을 저장할 수 있음
백터 메소드
- addElement() : 요소를 추가
- size() : 요소의 개수를 반환
- capacity() : 현재 벡터에 저장 가능한 크기를 반환
- get() : 인덱스로 저장된 값을 찾아 반환
- removeAllElements() : 저장된 모든 요소를 삭제
- set() : 인덱스로 저장된 값을 변경(설정)
참소변수.set(인덱스, 값);
Vector1 클래스
import java.util.Vector;
public class Vector1 {
public static void main(String[] args) {
Vector<String> vector = new Vector<>();
System.out.println("벡터 데이터의 길이 : " + vector.size());
System.out.println("벡터의 크기 : " + vector.capacity());
System.out.println();
vector.addElement("김사과");
vector.addElement("오렌지");
vector.addElement("반하나");
vector.addElement("박체리");
vector.addElement("배애리");
vector.addElement("김사과");
vector.addElement("이메론");
vector.addElement("반하나");
vector.addElement("안카도");
System.out.println("벡터 데이터의 길이 : " + vector.size());
System.out.println("벡터의 크기 : " + vector.capacity());
vector.addElement("반하나");
vector.addElement("안카도");
System.out.println("벡터 데이터의 길이 : " + vector.size());
System.out.println("벡터의 크기 : " + vector.capacity()); // 백터의 크기는 10개단위로 늘어나고, 데이터를 삭제해도 줄어들지 않음.
System.out.println();
System.out.println("백터의 두번째 요소 : " + vector.elementAt(1));// elementAt() : 해당 인덱스의 데이터를 반환.
System.out.println();
vector.remove(3); // remove() : 해당 인덱스 삭제
System.out.println("벡터 데이터의 길이 : " + vector.size());
System.out.println("벡터의 크기 : " + vector.capacity());
vector.remove(3);
System.out.println("벡터 데이터의 길이 : " + vector.size());
System.out.println("벡터의 크기 : " + vector.capacity());
System.out.println();
for (int i = 0; i < vector.size(); i++) {
System.out.print(vector.get(i) + " "); // get() : 해당 인덱스의 데이터를 반환.
}
System.out.println();
System.out.println("벡터의 2번째 요소 : " + vector.get(1));
vector.set(1, "안가도"); // set() : 해당 인덱스의 요소의 값 변경
System.out.println("벡터의 2번째 요소 : " + vector.get(1));
vector.removeAllElements(); // removeAllElements() : 벡터의 모든 데이터 삭제
System.out.println("벡터 데이터의 길이 : " + vector.size());
System.out.println("벡터의 크기 : " + vector.capacity()); // 데이터를 삭제해도 크기가 줄어들지 않음.
}
}
비주얼고
- https://visualgo.net/en/list?slide=1
List - Queue
Queue
- FIFO(First Input First Out)
- 큐의 한쪽 끝을 프론트(head)로 정하여 삭제 연산만 수행
- 다른 한쪽 끝을 리어(tail)로 정하여 삽입 연산만 수행
- 운영체제의 스케줄러, 푸쉬메시지
Queue 생성
Queue<타입> 참조변수명 = new LinkedList<>();
Queue 메소드
offer() : 요소를 추가
peek() : 첫번째 데이터를 반환
poll() : 첫번째 데이터를 반환하고 삭제
remove() : 값 제거
clear() : queue 초기화
Queue1 클래스
import java.util.LinkedList;
import java.util.Queue;
public class Queue1 {
public static void main(String[] args) {
Queue<Integer> queue = new LinkedList<>();
queue.offer(10); // offer() : 데이터 추가
queue.offer(50);
queue.offer(80);
queue.offer(20);
queue.offer(70);
System.out.println(queue); // 넣은 순서대로 반환
System.out.println(queue.peek()); // peek() : 첫번째 데이터 반환
System.out.println(queue.poll()); // poll() : 첫번째 데이터 반환하고 삭제
System.out.println(queue);
queue.remove(); // remove() : 데이터 삭제
// list 인터페이스에서 remove()는 꼭 구현해야하는 메소드이고, poll은 queue의 원래 특징적인 것이기 때문에 삭제 메소드가 두개 존재
System.out.println(queue);
queue.clear(); // 데이터 전체 삭제
System.out.println(queue);
}
}
List - Stack
Stack
- LIFO(Last Input First Out)
- 한쪽 끝에서만 자료를 넣고 뺄 수 있는 형식의 자료구조
- 브라우저의 "뒤로가기", "앞으로가기"
Stack 생성
Stack<타입> 참조변수명 = new Stack();
stack 메소드
push() : 요소를 저장
peek() : 마지막(첫번째로 뽑힐) 데이터를 반환
pop() : 마지막(첫번째로 뽑힐) 데이터를 반환하고 삭제
search() : 데이터의 순서를 반환(뽑힐 순서, 1~)
clear() : 데이터 전체 삭제
Stack1 클래스
import java.util.Stack;
public class Stack1 {
public static void main(String[] args) {
Stack<Integer> stack = new Stack();
stack.push(40); // push() : 데이터 저장
stack.push(100);
stack.push(80);
stack.push(50);
stack.push(20);
System.out.println(stack);
System.out.println(stack.peek()); // peek() : 마지막 요소 반환
System.out.println(stack);
System.out.println(stack.pop()); // pop() : 마지막 요소 반환 후 삭제
System.out.println(stack);
System.out.println(stack.search(40)); // search() : 데이터의 뽑힐 순서 반환(1부터 시작)
stack.clear(); // clear() : 데이터 전체 삭제
}
}
List - ArrayList
ArrayList
- 동적인 길이로 여러 데이터형을 저장하기 위해 사용
- 배열과 동일하게 정수 인덱스를 이용하여 액세스 할 수 있음
- 비동기식을 사용하고 멀티 스레드를 지원
ArrayList 생성
ArrayList<타입> 참조변수 = new ArrayList<>();
add() : 요소를 추가
size() : 요소의 개수를 반환
remove() : 인덱스를 이용하여 요소를 삭제
set() : 인덱스로 저장된 값을 변경(설정)
Iterator 인터페이스
컬렉션 프레임워크 인터페이스에서는 Iterator 인터페이스를 구현한 클래스의 인스턴스를 반환하는 iterator()
메소드를 정의하여 각 요소에 접근하도록 설계
- 자바의 컬렉션에 저장되어 있는 요소들을 읽어오는 방법
- 컬렉션으로부터 정보를 얻어내는 방법
Iterator의 장점과 단점
장점 : 컬렉션 프레임워크 종류에 상관없이 일관성 있게 프로그래밍을 할 수 있음
단점 : size 메소드를 얻어와서 반복 처리하는 것 보다 속도가 좋지 못함
import java.util.ArrayList;
import java.util.Iterator;
public class ArrayList1 {
public static void main(String[] args) {
ArrayList<Integer> arrayList = new ArrayList<>();
arrayList.add(80); // add() : 데이터 저장
arrayList.add(100);
arrayList.add(65);
arrayList.add(90);
arrayList.add(55);
System.out.println(arrayList);
for (int i = 0; i < arrayList.size(); i++) {
System.out.print(arrayList.get(i) + " "); // get() : 해당 인덱스의 데이터 반환
}
System.out.println();
arrayList.remove(2); // remove() : 해당 인덱스 삭제
System.out.println(arrayList);
arrayList.set(0, 60); // set() : 해당 인덱스의 값 변경
System.out.println(arrayList);
// Iterator : 컬렉션프레임워크의 데이터를 탐색
// Iterator<> : 탐색할 데이터의 자료형과 <>안의 데이터형은 일치해야 함.
Iterator<Integer> iterator = arrayList.iterator(); // Iterator<Integer> : Integer 형의 데이터 탐색가능.
while (iterator.hasNext()) { // hasNext() : 탐색할 데이터가 있는지 여부 반환
System.out.print(iterator.next() + " "); // next() : 탐색한 데이터를 반환
}
}
}
List - LinkedList
LinkedList
- 각 노드가 데이터와 포인터를 가지고 한 줄로 연결되어 있는 방식
- ArrayList에 비해 데이터의 추가나 삭제가 빠름
- 인덱스가 없기 떄문에 특정 요소에 접근이 느림
- 탐색속도가 떨어짐
import java.util.LinkedList;
public class LinkedList1 {
public static void main(String[] args) {
LinkedList<String> linkedList = new LinkedList<>();
linkedList.add("김사과");
linkedList.add("반하나");
linkedList.add("김사과");
linkedList.add("오렌지");
linkedList.add("이메론");
linkedList.add("박체리");
linkedList.add("배애리");
System.out.println(linkedList);
System.out.println(linkedList.peek()); // peek() : 첫번째에 뽑을 데이터 반환
System.out.println(linkedList);
System.out.println(linkedList.poll()); // poll() : 첫번째에 뽑을 데이터 반환하고 삭제
System.out.println(linkedList);
linkedList.remove("오렌지"); // remove() : 해당 데이터를 삭제
System.out.println(linkedList);
}
}
✅ 탐색 또는 정렬을 자주하는 경우에는 배열을 사용하고, 데이터의 추가/삭제가 많은 경우에는 링크드리스트를 사용하는 것이 좋음
⭐ 노드
데이터(값)와 포인터(주소)를 담고있는 형태
Set - HashSet
HashSet
- 데이터를 중복해서 저장할 수 없음 (중복을 자동으로 제거)
- 하나의 null 값만 저장할 수 있음
- 저장 순서가 유지되지 않음
- 정렬을 하지 않음
중복을 걸러내는 과정
1. hashCode()를 이용하여 저장되어 있는 객체들의 해시코드 값을 비교
2. equals()로 두 객체를 비교해서 true가 나오면 동일한 객체로 판단
HashSet 생성
HashSet<타입> 참조변수 = new HashSet();
HashSet 메소드
add() : 요소를 추가
size() : 요소의 개수를 반환
import java.util.HashSet;
import java.util.Iterator;
public class HashSet1 {
public static void main(String[] args) {
HashSet<String> hashSet1 = new HashSet<>();
HashSet<String> hashSet2 = new HashSet<>();
hashSet1.add("김사과");
hashSet1.add("반하나");
hashSet1.add("오렌지"); // 순서대로 저장되지 않음.
System.out.println(hashSet1);
hashSet1.add("김사과"); // 중복된 데이터는 삭제됨.
System.out.println(hashSet1);
for (String s : hashSet1) {
System.out.print(s + " ");
}
System.out.println();
System.out.println("요소의 개수 : " + hashSet1.size());
hashSet2.add("김사과");
hashSet2.add("반하나");
hashSet2.add("오렌지");
hashSet2.add("이메론");
System.out.println(hashSet2);
Iterator<String> iterator = hashSet2.iterator();
while (iterator.hasNext()) {
System.out.print(iterator.next() + " ");
}
}
}
Set - TreeSet
TreeSet
- 데이터를 중복해서 저장할 수 없음(중복을 자동으로 제거)
- 하나의 null 값만 저장할 수 있음
- 저장 순서가 유지되지 않음
- 이진 탐색 트리 구조로 이루어져 있음
- 오름차순으로 정렬
⭐ 이진 탐색 트리
추가와 삭제에는 시간이 걸리지만 정렬, 검색에 높은 성능을 자랑하는 자료구조
Map - HashMap
HashMap
- Map 인터페이스를 구현한 대표적인 클래스
- 키와 값으로 구성된 요소객체를 저장하는 구조를 가지고 있는 자료구조
- 키는 중복 저장될 수 없고, 값은 중복될 수 있음
- 기존에 저장된 키와 동일한 키로 값을 저장하면 기존의 값은 없어지고 새로운 값으로 대체
- 해싱(Hashing)을 사용하기 때문에 많은 양의 데이터를 검색하는데 뛰어난 성능
- 비동기식
key(apple) key 테이블 value 테이블
value(사과) ---------------> apple (해시함수) 사과
Map - TreeMap
TreeMap
- 이진트리를 기반으로 한 Map 클래스
- 키와 값이 저장된 Map, Entry를 저장함
- 키를 기준으로 오름차순 정렬
- HashMap보다 성능이 떨어짐
Map - HashTable
HashTable
- 키와 값의 데이터를 테이블에 저장
- 자바는 HashMap을 지원하기 때문에 HashTable을 구현하거나 사용하는 경우가 거의 없음
- 동기식
- null 입력이 불가능
Map - Properties
Properties
- HashTable을 상속받아 구현
- (String, String)의 형태로만 저장(메소드)
- 애플리케이션 환경설정과 관련된 속성을 저장할 때 종종 사용
- 컬렉션프레임워크 이전의 구버전이므로 Iterator가 아닌 Enumration(열거객체)를 사용