Chapter 11 컬렉션 프레임웍

Red Culture·2021년 6월 17일
0

컬렉션 프레임웍이란

프로그램 구현에 필요한 자료구조와 알고리즘을 구현한 라이브러리로 java.util 패키지에 구현되어 있다. Collection 인터페이스와 Map 인터페이스로 구성된다.

Collection 인터페이스


*참고자료 - 패스트캠퍼스 온라인 강의

  • List 인터페이스
    -Collection 하위 인터페이스로 객체를 순서에 따라 저장하고 관리하는데 필요한 메서드가 선언된 인터페이스, 배열의 기능을 구현하기 위한 메서드가 선언됨
    -ArrayList, Vector, LinkedList
    -데이터의 중복을 허용하며 null도 허용한다.

1) ArrayList와 Vector
-객체 배열 클래스로 Vector는 자바2부터 제공된 클래스이다. 일반적으로 ArrayList를 더 많이 사용하고, Vector는 멀티 쓰레드 프로그램에서 동기화를 지원한다. Vector는 모든 메서드에 syncronized 키워드가 들어가 있다.
동기화: 두 개의 쓰레드가 동시에 하나의 리소스에 접근할 때 순서를 맞춰서 데이터의 오류가 생기지 않도록 방지함
capacity와 size의 차이점: capacity는 메모리가 할당되어 있는 공간의 용량 , size는 배열 요소의 갯수

2) ArrayList와 LinkedList
-자료의 순차적 구조를 구현한 클래스
-ArrayList는 배열을 구현한 클래스로 논리적 순서와 물리적 순서가 동일하다. 물리적으로 붙어있는 자료구조이기 때문에 중간에 값이 들어가거나 빠지는데 소요시간이 많이 걸리고 배열의 확장이나 축소가 필요하면 copy가 필요하지만, 옵셋 만큼만 떨어뜨리면 되기 때문에 i번째 위치한 요소를 빨리 찾을 수 있다.
-LinkedList는 논리적으로 순차적 구조지만, 물리적으로는 순차적이지 않을 수 있다. i번째 요소를 처음부터 찾아야한다. next 요소에 대한 레퍼런스를 가지고 있고, 자료를 추가하거나 삭제하는데 들어가는 비용이 효율적이다. 동적 메모리가 허용되는 한 연결해서 사용할 수 있다.

  • Set 인터페이스
    -Set안의 타입(<>)이 관리할 객체가 논리적으로 같다라는 것에 대한 재정의가 필요하다. (equals, hashCode) (Integer나 String 같은 기존 클래스는 정의가 되어 있음)
    -key의 중복과 key로 null을 허용하지 않음 (List는 순서기반이지만, Set은 순서가 없음)
    -get(i) 메서드가 제공되지 않음 (Iterator로 순회)

1) HashSet 클래스
-Set 인터페이스를 구현한 클래스로 중복을 허용하지 않으므로 객체의 동일함 여부를 알기 위해 equals()와 hashCode() 메서드를 재정의 해야한다.

2) TreeSet 클래스
-객체의 정렬에 사용되는 클래스로 중복을 허용하지 않으면서 오름차순이나 내림차순으로 객체를 정렬한다.
-내부적으로 이진 검색 트리로 구현되어 있다.
-이진 검색 트리에 자료가 저장될 때 비교하여 저장할 위치를 정한다.
-객체 비교를 위해 Comparable이나 Comparator 인터페이스를 구현해야 한다.
-> Comparator 인터페이스를 구현하는 경우 TreeSet 생성자에 Comparator가 구현된 객체를 매개변수로 전달해야 한다.
-> TreeSet treeSet = new TreeSet<>(new Member());

class MyCompare implements Comparator<String> {

    @Override
    public int compare(String s1, String s2) {
        return s1.compareTo(s2) * (-1);     
    }
}

public class ComparatorTest {
    public static void main(String[] args) {
        TreeSet<String> treeSet = new TreeSet<>(new MyCompare());
        treeSet.add("홍길동");
        treeSet.add("강감찬");
        treeSet.add("이순신");

        for (String str : treeSet) {
            System.out.println(str);
        }

    }
}

Map 인터페이스

쌍으로 이루어진 객체를 관리하는데 필요한 여러 메서드가 선언되어 있고, Map을 사용하는 객체는 key-value 쌍으로 되어 있고, value는 중복을 허용하지만 key는 중복될 수 없다. key로 null을 허용하지 않는다. key를 이용하여 값을 저장하거나 검색, 삭제할 때 사용하면 편리하다. 내부적으로 hash 방식으로 구현되어 있다. (index = hash(key)) 키가 되는 객체는 객체의 유일성의 여부를 알기 위해 equals()와 hashCode() 메서드를 재정의한다.
values()에서는 반환 타입이 Collection이고, keySet()은 반환 타입이 Set이다. 값은 중복을 허용하고, 키는 중복을 허용하지 않기 때문이다.

*참고자료 - 패스트캠퍼스 온라인 강의

1) HashMap 클래스
-Map 인터페이스를 구현한 클래스 중 가장 일반적으로 사용하는 클래스이다. HashTable 클래스는 자바2부터 제공된 클래스로 Vector 처럼 동기화를 제공한다. pair 자료를 쉽고 빠르게 관리할 수 있다.

2) TreeMap 클래스
-key 객체를 정렬하여 key-value를 pair로 관리하는 클래스
-key에 사용되는 클래스에 Comparable, Comparator 인터페이스를 구현해야 한다.
-> 이미 많은 클래스들은 Comparable이 구현되어 있어서 구현된 클래스를 key로 사용하는 경우는 구현할 필요가 없다.

Stack과 Queue

-Stack: LIFO으로 맨 마지막에 추가된 요소가 가장 먼저 꺼내지는 자료구조
-Queue: FIFO로 먼저 들어간 것이 먼저 나오는 자료구조

Iterable, Iterator 인터페이스

Iterable 인터페이스는 컬렉션에 저장된 각 요소에 접근하는데 사용된다.
Collection 인터페이스의 상위 인터페이스가 Iterable이고, Iterable 인터페이스 안에는
Iterator<T> iterator(); 메서드가 추상 메서드로 선언이 되어 있다. 그렇기 때문에 Collection 인터페이스 계층구조에서 List, Set, Queue를 구현하는 클래스들은 다 iterator 메서드를 가지고 있다.

Iterator 인터페이스는 Collection과는 별개로 존재하는 인터페이스이다. 인터페이스 내부 구현은 hasNext(), next(), remove() 메서드가 있다.

public static void main(String[] args) {
    ArrayList<String> list = new ArrayList<>();
    list.add("A");
    list.add("B");
    list.add("C");

    HashSet<String> set = new HashSet<>();
    set.add("D");
    set.add("E");
    set.add("F");

    HashMap<String, Integer> map = new HashMap<String, Integer>();
    map.put("G", 1);
    map.put("H", 2);
    map.put("I", 3);

    Iterator<String> iteratorList = list.iterator();
    Iterator<String> iteratorSet = set.iterator();
    Iterator<String> iteratorMap = map.keySet().iterator();

    while(iteratorList.hasNext()) {
        System.out.println(iteratorList.next());
    }
    System.out.println("================");

    while(iteratorSet.hasNext()) {
        System.out.println(iteratorSet.next());
    }
    System.out.println("================");

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

-> Map 인터페이스를 구현한 컬렉션 클래스는 키와 값을 쌍으로 갖고 있기 때문에 iterator()를 직접 호출할 수 없고, 그 대신 keySet()이나 entrySet()같은 메서드를 통해 키와 값을 각각 따로 Set의 형태로 얻어 온 후에 다시 iterator()를 호출해야 Iterator를 얻을 수 있다.
-> map.keySet() : 키를 찾아서 리턴
-> map.entrySet() : 키와 value를 리턴
-> map.get(key) : 키의 value를 찾아서 리턴
-> map.values() : value만 리턴

Comparable과 Comporator 인터페이스의 차이점

Comparable은 "자기 자신과 매개변수 객체를 비교"하는 것이고, Comparator는 "두 매개변수 객체를 비교"한다는 것

  • Comparable은 lang 패키지에 있기 때문에 import 를 해줄 필요가 없지만, Comparator는 util 패키지에 있다. 이미 Comparable이 구현된 경우 Comparator를 이용하여 다른 정렬 방식을 정의할 수 있다.
    -> Comparable 인터페이스를 구현한 클래스는 기본적으로 오름차순으로 정렬된다. compareTo 메서드를 재정의 해야한다. 정수를 반환하며, 객체 자신(this)을 기준으로 매개변수와 차이 값을 비교하여 반환한다. (음수: 자신보다 매개변수가 더 크다. / 양수: 자신이 매개변수 보다 더 크다.)
    1) int compareTo
    -오름차순: 자기 자신 - 매개변수
    -내림차순: 매개변수 - 자기 자신
    2) 문자열 compareTo
    -문자열이 같은 경우 0 리턴
    -비교 대상이 문자열에 포함되는 경우 a.length - b.length 리턴 (a.compareTo(b))
    -다른 문자열인 경우 아스키코드의 차이값을 리턴
  • Comparator 인터페이스는 내림차순이나 아니면 다른 기준으로 정렬하고 싶을 때 사용할 수 있다. 이때 Comparator 인터페이스를 구현한 클래스에서는 compare() 메서드를 재정의하여 사용하게 된다. 객체 자체와는 상관 없이 독립적으로 매개변수로 넘겨진 두 객체를 비교하는 것

*참고 자료
https://devlog-wjdrbs96.tistory.com/84
https://yongku.tistory.com/entry/%EC%9E%90%EB%B0%94Java-CompareTo-%EB%A9%94%EC%86%8C%EB%93%9C

profile
자기 개발, 학습 정리를 위한 블로그

0개의 댓글