본문 바로가기
Study/JAVA

[2022-11-30] Java의 정석 2 - 11. 컬렉션 프레임웍

by 까다로운오리 2022. 11. 30.

 

컬렉션 프레임웍?

'데이터군을 저장하는 클래스들을 표준화한 설계'

 

컬렉션데이터 그룹은 크게 3가지 타입이 존재.

 

1. List

- 순서가 있는 데이터의 집합. 데이터의 중복을 허용한다

구현 클래스 : ArrayList, LinkedList, Stack, Vector 등

 

ArrayList

ArrayList는 Object배열을 이용해서 데이터를 순차적으로 저장한다. 첫번째로 저장한 객체는 0번째 위치에 저장된다. 배열에 더 이상 저장할 공간이 없으면 보다 큰 새로운 배열을 생성해서 기존의 배열에 저장된 내용을 새로운 배열로 복사한 다음에 저장된다.

 

 

import java.util.*;


class ArrayListEx1 {

    public static void main(String[] args) {
    	ArrayList list1 = new ArrayList(10);
        list1.add(new Integer(5));
        list1.add(new Integer(4));
        list1.add(new Integer(2));
        list1.add(new Integer(0));
        list1.add(new Integer(1));
        list1.add(new Integer(3));
        
    	ArrayList list2 = new ArrayList(list1.subList(1,4));
		print(list1, list2);
       	// list1: [5,4,2,0,1,3]
        // list2: [4,2,0]
        
        
        Collections.sort(list1);
        Collections.sort(list2);
        print(list1, list2);
        
        // list1: [0,1,2,3,4,5]
        // list2: [0,2,4]
        
        System.out.println("list1.containsAll(list2):" + list1.containsAll(list2));
        
       	// list1.containsAll(list2): true
        
        
        list2.add("B");
        list2.add("C");
        list2.add(3,"A");
        print(list1, list2);
        
        // list1: [0,1,2,3,4,5]
        // list2: [0,2,4,"A","B","C"]
        
        
        System.out.println("list1.containsAll(list2):" + list1.containsAll(list2));
        
       	// list1.containsAll(list2): true
        
        list2.set(3,"AA");
        // list1: [0,1,2,3,4,5]
        // list2: [0,2,4,"AA","B","C"]
        
        
        for (int i = list2.size()-1; i >=0; i--) {
        	if (list1.contains(list2.get(i))
            	list2.remove(i);
            }
        print(list1, list2);
        // list1: [0,1,2,3,4,5]
        // list2: ["AA","B","C"]
        
   }
   
   static void print(ArrayList list1, ArrayList list2) {
       System.out.println("list1:"+list1);
       System.out.println("list2:"+list2);
       System.out.println();
  	     
 }

 

*** ArrayList를 생성할 때, 저장할 요소의 개수를 고려해 실제 저장할 개수보다 약간 여유있는 크기로 하는 것이 좋다.

 

 

LinkedList

배열의 단점을 보완하기 위해 만들어진 자료구조. Java의 링크드리스트는 실제로 더블링크드리스트로 구현되어 있음. 더블 링크드리스트는 그림과 달리 마지막 링크가 향하는 것은 null이 첫번째를 가리키고 첫번째 또한 마지막을 가리킨다.

 

스택은 ArrayList로 큐는 추가/삭제가 쉬운 LinkedList로 구현한다.

 

 

Iterator, ListIterator , Enumeration

:컬렉션에 저장된 요소를 접근하는데 사용되는 인터페이스

 

기능

Enumeration < Iterator < ListIterator

 

Iterator

public interface Iterator {
   boolean hasNext(); // 읽어 올 요소가 남아있는지 확인한다. 있으면 ture 없으면 false를 반환
   Object next(); // 다음 요소를 읽어 온다. next()를 호출하기 전에 hasNExt()를 호출해서 읽어 올 요소가 있는지 확인하는 것이 안전하다.
   void remove(); // next()로 읽어 온 요소를 삭제한다. next()를 호출한 다음에 remove()를 호출해야 한다.
   
}

public interface Collection {
    ...
    public Iterator iterator();
    ...
}

 

ArrayList에 저장된 요소들을 출력하기 위한 코드는 다음과 같이 작성할 수 있는데,

 

Collection c = new ArrayList();
Iterator it = c.iterator();

while (it.hasNext()) {
    System.out.println(it.next());
}

참조변수 타입을 ArrayList가 아니라 Collection타입으로 한 이유?

만일 Collection인터페이스를 구현한 다른 클래스, 예를 들어 LinkedList로 바꿔야 한다면 선언문 하나만 변경하면 나머지 코드는 검토하지 않아도 된다.

 

Map인터페이스를 구현한 컬렉션 클래스는 키와 값을 쌍으로 지정하고 있기 때문이 iterator()를 직접 호출할 수 없고 그 대신 keySet()이나 entrySet()과 같은 메서드를 통해서 키와 값을 각각 따로 Set의 형태로 얻어 온 후 다시 iterator()를 호출해야 Iterator()를 얻을 수 있다.

Map map = new HashMap();
	...
Iterator it = map.entrySet().iterator();

// Set eSet - map.entrySet()
// Iterator it = eSet.Iterator(); 와 같은 말

 

ListIterator , Enumeration

 

Enumeration : Iterator의 구버젼 

ListIterator  : Iterator를 상속받아서 기능을 추가한 것이다. Iterator에 양방향 조회기능추가 (List를 구현한 경우만 사용 가능)

 

표 11-14 ListIterator인터페이스의 메서드

 

Arrays

 

배열의 복사

: copyOf() - 전체 복사

: copyOfRange() - 일부 복사

 

배열 채우기

: fill() - 배열의 모든 요솔르 지정된 값으로 채운다

: setAll() - 호출시 함수형 인터페이스를 구현한 객체를 매개변수로 지정 or 람다식 지정

 

배열의 정렬과 검색

sort() - 정렬

binarySearch() - 검색

 

배열의 비교와 출력

equals() - 비교

toString() - 배열의 모든 요소를 문자열로 출력

 

배열을 리스트로 변환

asList(Object... a) // 단, 리스트 크기 변경 불가 (추가, 삭제 불가)

 

 

Comparator와 Comparable

컬렉션을 정렬하는데 필요한 메서드를 정의한다. 

 

Comparable 기본 정렬기준을 구현하는데 사용

Comparator 기본 정렬 기준 외에 다른 기준으로 정렬하고자할 때 사용

 

 


2. Set

-순서를 유지하지 않는 데이터의 집합. 데이터의 중복을 허용하지 않는다. 

구현 클래스 : HashSet, TreeSet 등

 

HashSet

순서 x, 순서 유지 하고 싶으면 LinkedHashSet을 사용

TreeSet

이진 검색 트리 라는 자료구조의 형태로 데이터를 저장하는 컬렉션 클래스 이다. 중복된 데이터의 저장을 허용하지 않으면서 정렬된 위치에 저장하므로 저장 순서를 유지하지도 않는다. 왼쪽에는 부모보다 작은 값 오른쪽은 부모보다 큰 값을 넣는다.

 

이진검색트리

- 모든 노드는 최대 두개의 자식 노드

- 왼쪽 자식 < 부모 < 오른쪽 자식

- 노드의 추가 삭제에 시간이 걸리낟

- 검색과 정렬에 유리하다.

- 중복 값을 저장하지 못한다.

 


3. Map

- 키와 값의 쌍으로 이루어진 데이터의 집합

- 순서는 유지되지 않으며, 키는 중복을 허용하지 않고, 값은 중복을 허용한다.

구현 클래스 :  HashMap, TreeMap, Hashtable, Properties 등

 

HashMap

키와 값을 Object타입으로 지정한다.

Entry[] table;
class Entry {
    Object key;
    Object value;
}

 

해싱과 해시함수

해싱이란 해시함수를 이용하여 데이터를 해시테이블에 저장하는 기법이다. 해시함수는 데이터가 저장되어 있는 곳을 알려 주기 때문에 다량을 데이터 중에서도 원하는 데이터를 빠르게 찾을 수 있다.

 

 

TreeMap

이진트리형태로 키와 값의 쌍으로 이루어진 데이터를 저장. 검색과 정렬에 적합한 컬렉션 클래스

 

 

Collections

컬렉션과 관련된 메서드를 제공한다. 

 

1. 변경 불가 컬렉션 만들기

2. 하나의 객체만을 저장한는 싱글톤 컬렉션 만들기 기능

 

 

 

종합~