Java

[Java] 컬렉션 프레임워크

에띠 2022. 4. 17. 15:24
728x90

✅ 컬렉션 프레임워크
- 여러가지 데이터를 메모리에서 쉽고 효과적으로 처리할 수 있는 표준화된 방법을 제공하는 클래스들의 집합
- 자료구조를 구현한 클래스의 모음

⭐ 자료구조
- 데이터를 효율적으로 관리할 수 있는 데이터 구조를 의미
- 데이터의 특성에 따라 체계적으로 구조화함

⭐ 알고리즘
- 어떤 문제를 풀기 위한 절차 및 방법
- 어떤 문제에 대해 입력을 넣으면 원하는 출력을 얻을 수 있도록 만드는 프로그래밍


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(열거객체)를 사용

 

728x90