Java 컬렉션 프레임워크
컬렉션 프레임워크(Collection Framework)
어플리케이션을 개발하다 보면 다수의 객체를 저장해 두고 필요할 때마다 꺼내서 사용하는 경우가 많다.
예를 들어 배열같은 경우 다수의 객체를 저장할 수 있으나, 저장할 수 있는 객체의 수가 처음 선언할때 결정되기 때문에 불측정 다수의 객체를 저장하는데는 문제가 있다.
이러한 문제점을 해결하기 위해 널리 알려져 있는 Data Structure를 바탕으로 객체들을 효율적으로 추가, 삭제, 검색할 수 있도록 java.util 패키지에 컬렉션과 관련된 인터페이스와 클래스를 포함시켜 두었다.
- Collection
- List(순서를 유지하고 저장, 중복저장 가능)
- ArrayList
- Vector
- LinkedList
- Set(순서를 유지하지 않고 저장, 중복저장 안됨)
- HashSet
- TreeSet
- List(순서를 유지하고 저장, 중복저장 가능)
- Map(키와 값의 쌍으로 저장, 키는 중복저장 안됨)
- HashMap
- HashTable
- TreeMap
- Properties
List Collection
- 공통메소드
기능 | 메소드 | 설명 |
---|---|---|
객체추가 | boolean add(E e) | 주어진 객체를 맨 끝에 추가 |
void add(int index, E element) | 주어진 인덱스에 객체를 추가 | |
set(int index, E element) | 주어진 인덱스에 저장된 객체를 주어진 객체로 바꿈 | |
객체검색 | boolean contains(Object O) | 주어진 객체가 저장되어 있는지 여부 |
E get(int index) | 주어진 인덱스에 저장된 객체를 리턴 | |
isEmpty() | 컬렉션이 비어있는지 확인 | |
int size() | 저장되어 있는 전체 객체 수를 리턴 | |
객체삭제 | void clear() | 저장된 모든 객체를 삭제 |
E remove(int index) | 주어진 인덱스에 저장된 객체를 삭제 | |
boolean remove(Object O) | 주어진 객체를 삭제 |
ArrayList
- ArrayList는 일반 배열과 같이 인덱스로 객체를 관리한다는 점에서는 유사
- 배열은 생성할 때 크기가 고정되고 사용중에 크기를 변경할 수 없지만 ArrayList는 저장용량을 초과한 객체들이 들어오면 자동으로 저장용량 늘어남.
-
ArrayList에서 특정 인덱스가 삭제 되면 모두 앞으로 1씩 당겨진다.
import java.util.*; public class ArrayListExample{ public static void main(String[] args){ // ArrayList 객체 생성 List<String> list = new ArrayList<String>(); // ArrayList에 객체 추가 list.add("First"); // 순서대로 추가 list.add("Second"); list.add("Third"); list.add(2, "fourth"); // 2번 인덱스에 fourth 추가 // First, Second, fourth, Third 저장되어 있음 // ArrayList안의 객체 수 확인하기 int size = list.size(); System.out.println("객체 수: " + size); // ArrayList안의 객체 전체 출력 for(int i=0; i<list.size(); i++){ String str = list.get(i); System.out.println(i + ":" + str); } // ArrayList 안의 객체 삭제 list.remove(2) // 2번 인덱스 삭제 (fourch) list.remove("First") } }
Vector
- ArrayList와 비슷하나 Vector는 동기화된 메소드들로 구성되어 있기 때문에 멀티스레드가 동시에 이 메소드들을 실행할 수 없고 하나의 스레드가 실행완료 해야만 다른 스레드가 사용가능하다.
-
이러한 특성으로 멀티스레드 환경에서 안전하게 객체를 추가, 삭제 가능하며 이를 Thread safe 하다 라고 한다.
import java.util.*; public class VectorExample{ public static void main(String[] args){ List<Board> list = new Vector<Board>(); // vector 추가 list.add(new Board("제목1", "내용1", "글쓴이1")); list.add(new Board("제목2", "내용2", "글쓴이2")); list.add(new Board("제목3", "내용3", "글쓴이3")); // vector 삭제 list.remove(2); // vector 출력 for(int i=0; i<list.size(); i++){ Board board = list.get(i) System.out.println(board.subject + "\t" + board.content + "\t" + board.writer); } } }
LinkedList
- LinkedList에서 특정 인덱스의 객체를 제거하면 앞뒤의 링크만 변경되고 나머지 링크는 변경되지 않는다.
- 빈번한 객체 삭제와 삽입이 일어나는 곳에서는 ArrayList보다 LinkedList 가 효율이 좋다.
-
하지만 순차적인 추가 삭제, 검색에서는 ArrayList가 좋은 효율을 보인다.
import java.util.*; public class LinkedListExample{ public static void main(String[] args){ List<String> list = new LinkedList<String>(); // LinkedList 추가 list.add("First"); // LinkedList 제거 list.remove(0); } }
Set Collection
- 공통메소드
기능 | 메소드 | 설명 |
---|---|---|
객체추가 | boolean add(E e) | 주어진 객체를 저장 객체가 성공적으로 저장되면 true 리턴하고 중복객체면 false 를 리턴 |
객체검색 | boolean contains(Object O) | 주어진 객체가 저장되어 있는지 여부 |
isEmpty() | 컬렉션이 비어있는지 확인 | |
Iterator |
저장된 객체를 한 번씩 가져오는 반복자 리턴 | |
int size() | 저장되어 있는 전체 객체 수를 리턴 | |
객체삭제 | void clear() | 저장된 모든 객체를 삭제 |
boolean remove(Object O) | 주어진 객체를 삭제 |
HashSet
-
객체들을 순서없이 저장하고 동일한 객체는 중복저장하지 않는다.
import java.util.*; public class HashSetExample{ public static void main(String[] args){ Set<String> set = new HashSet<String>(); // HashSet 추가 set.add("First"); set.add("Second"); set.add("Third"); set.add("fourth"); set.add("Second"); // Second는 한번만 저장됨. // 반복자 얻고 출력 Iterator<String> iterator = set.iterator(); while(iterator.hasNext()){ String element = iterator.next(); System.out.println("\t" + element); } // HashSet 삭제 set.remove("First"); // HashSet 초기화 set.clear() if(set.isEmpty()){System.out.println("Empty");} } }
TreeSet
- 이진 트리를 기반으로 한 Set 컬렉션이다.
-
하나의 노드는 노드 값인 value와 왼쪽 오른쪽 자식 노드를 참조하기 위한 left, right 변수가 있다.
리턴타입 메소드 설명 E first() 제일 낮은 객체를 리턴 E last() 제일 높은 객체를 리턴(root노드) E lower(E e) 주어진 객체보다 바로 아래 객체를 리턴 E higher(E e) 주어진 객체보다 바로 위의객체를 리턴 E floor(E e) 주어진 객체와 동등한 객체가 있으면 리턴 없으면 주어진 객체의 바로 아래의 객체를 리턴 E ceiling(E e) 주어진 객체와 동등한 객체가 있으면 리턴 없으면 주어진 객체의 바로 위의 객체를 리턴 E pollFisrt() 제일 낮은 객체를 꺼내오고 컬렉션에서 제거함 E pollLast() 제일 높은 객체를 꺼네오고 컬렉션에서 제거함 import java.util.TreeSet; public class TreeSetExample{ public static void main(String[] args){ // TreeSet 객체 생성 TreeSet<Integer> scores = new TreeSet<Integer>(); // TreeSet 추가 scores.add(new Integer(87)); scores.add(new Integer(98)); scores.add(new Integer(75)); scores.add(new Integer(95)); scores.add(new Integer(80)); // TreeSet 내 메소스 활용 Integer Score = null; score = scores.first(); // 가장 낮은 점수 75 저장 score = scores.last(); // 가잔 높은 점수 98 저장 score = scores.lower(new Integer(95)); // 95점 아래 점수인 87 저장 score = scores.higher(new Integer(95)); // 95점 위의 점수인 98 저장 score = scores.floor(new Integer(95)); // 95점 또는 바로 아래의 수인 95 저장 score = scores.ceiling(new Integer(85)); // 85점 이거나 바로 위의 수인 87 저장 while(!scores.isEmpty()){ score = scores.pollFirst(); // 낮은 숫자 부터 score에 저장하고 scores tree에서 삭제 } } }
Map
HashMap
- Map 인터페이스를 구현한 대표적인 Map 컬랙션
-
HashMap을 생성하기 위해서는 키 타입과 값 타입을 파라미터로 주고 기본 생성자를 호출하면 된다.
import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.Set; public class HashMapExample{ public static void main(String[] args){ // HashMap 객체 생성 Map<String, Integer> map = new HashMap<String, Integer>(); // HashMap에 객체 저장 map.put("가", 85); map.put("나", 90); map.put("디", 80); map.put("리", 95); // HashMap Entity 크기 출력 System.out.println("총 Entity 수 : " + map.size()); // 객체 찾기 System.out.println("가 : " + map.get("가")); // 객체를 하나씩 처리하는 방법 Set<String> KeySet = map.ketSet(); Iterator<String> keyIterator = keySet.iterator(); while(keyIterator.hasNext()){ String key = keyIterator.next(); Integer value = map.get(key); System.out.println(key + ":" + value); } // 객체 삭제 map.remove("가"); // 객체 전체 삭제 map.clear(); } }
HashTable
- HashMap과 동일한 내부 구조를 가지고 있지만 Vector와 같이 동기화된 메소드로 구성되어 있어 멀티 스레드가 동시에 이 메소드들을 실행할 수 없다.
import java.util.HashTable; public class HashTableExample{ public static void main(String[] args){ // HashTable 객체 생성 Map<String, String> map = new HashTable<String, String>(); // HashTable에 객체 저장 map.put("가", "85"); map.put("나", "90"); map.put("디", "80"); map.put("리", "95"); // HashTable Entity 크기 출력 System.out.println("총 Entity 수 : " + map.size()); // 객체 찾기 System.out.println("가 : " + map.get("가")); // 객체를 하나씩 처리하는 방법 Set<String> KeySet = map.ketSet(); Iterator<String> keyIterator = keySet.iterator(); while(keyIterator.hasNext()){ String key = keyIterator.next(); Integer value = map.get(key); System.out.println(key + ":" + value); } // 객체 삭제 map.remove("가"); // 객체 전체 삭제 map.clear(); } }
TreeMap
- 이진트리를 기반으로 한 Map 컬랙션이다.
- TreeSet과의 차이점은 키와 값이 저장된 Map.Entity를 사용한다는 것.
- 기본적으로 키값 비교를 통해 트리를 구성한다.
Properties
- HashTable의 하위 클래스로 HashTable의 모든 특징을 그대로 가지고 있다.
- 차이점으로는 HashTable 은 다양한 키와 값을 다양한 형태로 저장할 수 있지만 Properties는 키와 값을 String으로만 제한 한 것.
LIFO, FIFO 컬랙션
Stack
리턴타입 | 메소드 | 설명 |
---|---|---|
E | push(E item) | 주어진 객체를 스텍에 넣는다. |
E | peek() | 스택의 맨 위 객체를 가저온다. 객체는 삭제 x |
E | pop() | 스텍의 맨 위 객체를 가져온다. 객체 삭제 |
- Coin.java
public class Coin{ private int value; public Coin(int value){ this.value = value; } public int getValue(){ return value; } }
- StackExample.java
import java.util.*; public calss StackExample{ public static void main(String[] args){ Stack<Coin> coinbox = new Stack<Coin>(); coinbox.push(new Coin(100)); coinbox.push(new Coin(50)); coinbox.push(new Coin(500)); coinbox.push(new Coin(10)); while(!coinbox.isEmpty()){ Coin coin = coinbox.pop(); System.out.println("pop coin: " + coin.getValue()); } } }
Queue
리턴타입 | 메소드 | 설명 |
---|---|---|
boolean | offer(E e) | 주어진 객체를 넣는다. |
E | peek() | 객체 하나를 가져온다. 객체에서 큐를 제거하지 않는다. |
E | poll() | 객체 하나를 가져온다. 객체에서 큐를 제거한다. |
- Message.java
public class Message{ public String command; public String to; public Message(String command, String to){ this.command = command; this.to = to; } }
- QueueExample.java
import java.util.*; public calss QueueExample{ public static void main(String[] args){ Queue<Message> messageQueue = new LinkedList<Message>(); messageQueue.offer(new Message("A", "가")); messageQueue.offer(new Message("B", "나")); messageQueue.offer(new Message("C", "다")); while(!messageQueue.isEmpty()){ Message message = messageQueue.poll(); System.out.println("poll message: " + message.command + " to : " message.to); } } }