java day9
컬렉션 프레임워크 | List | Set | Map |
컬렉션 프레임워크
자바는 널리 알려져 있는 자료구조를 사용해서 객체들을 효율적으로 추가, 삭제, 검색 할 수 있도록 인터페이스와 구현 클래스를 java.util 패키지에서 제공함. 이들을 총칭해서 컬랙션 프레임워크라고 부름. 여러가지 데이터를 메모리에서 쉽고 효과적으로 처리할 수 있는 표준화된 방법을 제공하는 클래스들의 집합임.
자료구조
- 데이터를 효율적으로 관리할 수 있는 데이터 구조
- 데이터의 특성에 따라 체계적으로 구조화함
알고리즘
- 어떤 문제를 풀기 위한 절차 및 방법
- 어떤 문제에 대해 입력을 넣으면 원하는 출력을 얻을 수 있도록 만드는 프로그래밍
Iterator 인터페이스
컬렉션 프레임워크 인터페이스에서는 Iterator 인터페이스를 구현한 클래스의 인스턴스를 반환하는 iterator() 메소드를 정의하여 각 요소에 접근하도록 설계
- 자바의 컬렉션에 저장되어 있는 요소들을 읽어오는 방법
- 컬렉션으로 부터 정보를 얻어내는 방법
- Iterator 의 장점과 단점 장점 : 컬렉션 프레임워크 종류에 상관없이 일관성 있게 프로그래밍을 할 수 있음 단점 : size 메소드를 얻어와서 반복 처리하는 것 보다 속도가 좋지않음
List 인터페이스
- 순서가 있는 데이터들의 집합으로 데이터의 중복을 허용
- Vector, ArrayList, LinkedList, Stack, Queue
-
Vector 클래스
- 동적인 길이로 여러 데이터형을 저장하기 위해 사용
- 자바 1.0부터 존재하는 레거시 클래스
- 배열과 동일하게 정수 인덱스를 이용하여 액세스 할 수 있음
- (👍)동기화 되어 있으며 한번에 하나의 스레드만 벡터의 메소드를 호출 할 수 있음
Vector<타입> 참조변수 = new Vector<>(요소의 개수); addElement() : 요소를 추가 size() : 요소의 개수를 반환 capacity() : 현재 벡터에 저장 가능한 크기를 반환 get() : 인덱스로 저장된 값을 찾아 반환 removeAllElement() : 저장된 모든 요소를 삭제 set() : 인덱스로 저장된 값을 변경(설정) 참조변수.set(인덱스, 값);
-
ArrayList
- 동적인 길이로 여러 데이터형을 저장하기 위해 사용
- 배열과 동일하게 정수 인덱스를 이용하여 엑세스할 수 있음
- 비동기식을 사용하며 멀티 스레드를 지원
ArrayList<타입> 참조변수 = new ArrayList(); add() : 요소를 추가 size() : 요소의 개수 반환 remove() : 인덱스를 이용하여 요소를 삭제 set() : 인덱스로 저장된 값을 변경(설정)
public static void main(String[] args) { ArrayList<Integer> arrayList = new ArrayList<>(); arrayList.add(80); // 요소 추가 arrayList.add(100); arrayList.add(65); arrayList.add(90); arrayList.add(55); System.out.println(arrayList); // [80, 100, 65, 90, 55] for (int i = 0; i < arrayList.size(); i++) { System.out.print(arrayList.get(i) + " "); // 80 100 65 90 55 } System.out.println(""); arrayList.remove(2); // 인덱스 System.out.println(arrayList); // [80, 100, 90, 55] arrayList.set(0,60); // 해당 인덱스의 값 바꾸기 System.out.println(arrayList); // [60, 100, 90, 55] // 탐색 Iterator<Integer> iterator = arrayList.iterator(); while(iterator.hasNext()){ System.out.print(iterator.next() + " "); // 60 100 90 55 } System.out.println(""); }
-
LinkedList
- 각 노드가 데이터와 포인터를 가지고 한 줄로 연결되어 있는 방식
- ArrayList 에 비해 데이터의 추가나 삭제가 빠름
- 인덱스가 없기 때문에 특정요소에 접근이 느림
- 탐색속도가 떨어짐
public static void main(String[] args) { LinkedList<String> linkedList = new LinkedList<>(); linkedList.add("김사과"); linkedList.add("김하나"); linkedList.add("김렌지"); linkedList.add("김메론"); System.out.println(linkedList); // [김사과, 김하나, 김렌지, 김메론] System.out.println(linkedList.peek());// 김사과 : 첫번째 데이터 반환 System.out.println(linkedList.poll());// 김사과 : 첫번째 데이터 반환 및 삭제 System.out.println(linkedList); // [김하나, 김렌지, 김메론] linkedList.remove("김렌지"); // 입력값 삭제 System.out.println(linkedList); // [김하나, 김메론] }
탐색 또는 정렬을 자주하는 경우에는 ArrayList을 사용하고, 데이터의 추가/삭제가 많은 경우에는 LinkedList를 사용하는 것이 좋다.
-
Stack
- LIFO(Last input First out)
- 한쪽 끝에서만 자료를 넣고 뺄 수 있는 형식의 자료구조
- 브라우저의 “뒤로가기”, “앞으로가기”
Stack<타입> 참조변수 = new Stack<>(); push() : 요소를 저장 peek() : 마지막 데이터(첫번째 뽑힐)를 반환 pop() : 마지막(첫번째 뽑힐) 데이터를 반환 하고 삭제 search() : 데이터의 순서를 반환 clear() : 저장된 모든 요소를 삭제
public static void main(String[] args) { Stack<Integer> stack = new Stack<>(); stack.push(40); // 요소 추가 stack.push(100); stack.push(80); stack.push(50); stack.push(20); System.out.println(stack); // [40, 100, 80, 50, 20] : 순서 있음 System.out.println(stack.peek()); // 20 : 마지막 데이터 반환 System.out.println(stack); // [40, 100, 80, 50, 20] System.out.println(stack.pop()); // 20 : 마지막 데이터 반환 및 삭제 System.out.println(stack); // [40, 100, 80, 50] System.out.println(stack.search(40)); // 4 : 뽑힐 순서[ 4, 3, 2, 1] stack.clear(); // 데이터 모두 삭제 System.out.println(stack); // [] }
-
Queue
- FIFO(First in First out)
- 큐는 한쪽 끝을 프론트로 정하여 삭제 연산만 수행
- 다른 한쪽 큐를 리어로 정하여 삽입 연산만 수행함
- 운영체제의 스케줄러, 푸시 메세지
Queue<타입> 참조변수 = new LinkedList<>(); offer() : 요소 추가 peek() : 첫번째 데이터를 반환 poll() : 첫번째 데이터를 반환하고 삭제 remove() : 값 제거 clear() : 저장된 모든 요소를 삭제
public static void main(String[] args) { Queue<Integer> queue = new LinkedList<>(); queue.offer(10); queue.offer(50); queue.offer(80); queue.offer(20); queue.offer(70); System.out.println(queue); // [10, 50, 80, 20, 70], 순서가 있음 System.out.println(queue.peek()); // 10, 첫번째 데이터를 반환 queue.poll(); // 첫번째 데이터 삭제 System.out.println(queue); // [50, 80, 20, 70] queue.remove(); // 첫번째 데이터 삭제 System.out.println(queue); // [80, 20, 70] queue.clear(); // 모든 데이터 삭제 System.out.println(queue); // [] }
Set 인터페이스
- 순서가 없는 데이터 집합으로 데이터의 중복을 허용하기 않음
- HashSet, TreeSet
-
HashSet
- 데이터를 중복해서 저장할 수 없음(중복을 자동으로 제거)
- 하나의 null 값만 저장할 수 있음
- 저장 순서가 유지되지 않음
- 중복을 걸러내는 과정
- hashcode()를 이용하여 저장되어 있는 객체들의 해시 코드 값을 비교
- equals()로 두 객체를 비교해서 true 가 나오면 동일한 객체로 판단
HashSet<타입> 참조변수 = new HashSet(); add() : 요소를 추가 size() : 요소의 개수를 반환
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()); // 3 hashSet2.add("김사과"); hashSet2.add("반하나"); hashSet2.add("오렌지"); System.out.println(hashSet2); // [반하나, 김사과, 오렌지] // 탐색 Iterator<String> iterator = hashSet2.iterator(); while(iterator.hasNext()){ System.out.print(iterator.next() + " "); // 반하나 김사과 오렌지 } System.out.println(""); }
-
TreeSet
- 데이터를 중복해서 저장할 수 없음(중복을 자동으로 제거)
- 하나의 null값만 저장할 수 있음
- 저장 순서가 유지되지 않음
- 이진 탐색 트리 구조로 이루어져있음
🎁 이진 탐색 트리 : 추가와 삭제에는 시간이 걸리지만 정렬, 검색에 높은 성능을 자랑라는 자료구조
- 오름차순으로 정렬
public static void main(String[] args) { TreeSet<Integer> treeSet = new TreeSet<>(); treeSet.add(10); treeSet.add(8); treeSet.add(20); treeSet.add(35); treeSet.add(21); treeSet.add(4); System.out.println(treeSet); // [4, 8, 10, 20, 21, 35] treeSet.remove(20); System.out.println(treeSet); // [4, 8, 10, 21, 35] System.out.println(treeSet.size()); // 5 : 요소 개수 System.out.println(treeSet.first()); // 4 : 첫번째 데이터 System.out.println(treeSet.last()); // 35 : 마지막 데이터 System.out.println(treeSet.higher(21)); // 35 : 21 다음 데이터 System.out.println(treeSet.lower(21)); // 10 : 21 이전 데이터 for(int i : treeSet){ System.out.print(i + " "); //4 8 10 21 35 } System.out.println(); }
Map 인터페이스
- 키와 값을 한 쌍으로 이루어지는 데이터의 집합으로 순서가 없고, 키는 중복으로 허용하지 않지만 값은 중복될 수 있음
- HashMap, TreeMap, HashTable, Properties
-
HashMap
- Map 인터페이스를 구현한 대표적인 클래스
- 키와 값으로 구성된 요소 객체를 저장하는 구조를 가지고 있는 자료구조
- 키는 중복 저장될 수 없고, 값은 중복될 수 있음
- 기존에 저장된 키와 동일한 키로 값을 저장하면 기존의 값은 없어지고 새로운 값으로 대체
- 해싱(Hashing) 을 사용하기 때문에 많은 양의 데이터를 검색하는데 뛰어난 성능
- 비동기식
key(apple) key 테이블 value 테이블 value(사과) ——> apple (해싱함수) 사과
-
TreeMap
- 이진트리를 기반으로 한 Map 클래스
- 키와 값이 저장된 Map, Entry 를 저장
- 키를 기분으로 오름차순 정렬
- HashMap 보다 성능이 떨어짐
-
HashTable
- 키와 값의 데이터를 데이블에 저장
- 자바는 HashMap 을 지원하기 때문에 hashTable 을 구현하거나 사용하는 경우가 거의 없음
- 동기식
- null 입력이 불가능
-
Properties
- HashTable 을 상속받아 구현
- (String, String)의 형태로 저장(메소드)
- 애플리케이션 환경설정과 관련된 속성을 저장할 때 종종 사용
- 컬렉션 프레임워크 이전의 구버전이므로 Iterator 가 아닌 Enum(열거체) 를 사용