Java 컬렉션 프레임워크

컬렉션 프레임워크(Collection Framework)


어플리케이션을 개발하다 보면 다수의 객체를 저장해 두고 필요할 때마다 꺼내서 사용하는 경우가 많다.

예를 들어 배열같은 경우 다수의 객체를 저장할 수 있으나, 저장할 수 있는 객체의 수가 처음 선언할때 결정되기 때문에 불측정 다수의 객체를 저장하는데는 문제가 있다.

이러한 문제점을 해결하기 위해 널리 알려져 있는 Data Structure를 바탕으로 객체들을 효율적으로 추가, 삭제, 검색할 수 있도록 java.util 패키지에 컬렉션과 관련된 인터페이스와 클래스를 포함시켜 두었다.

  • Collection
    • List(순서를 유지하고 저장, 중복저장 가능)
      • ArrayList
      • Vector
      • LinkedList
    • Set(순서를 유지하지 않고 저장, 중복저장 안됨)
      • HashSet
      • TreeSet
  • 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 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);
              }
          }
      }