ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Java Collection Framework
    Computer Science 2020. 12. 21. 14:58

    컬렉션은 기본 데이터형이 아닌, 참조 데이터형만 저장이 가능하다는 것이다. 따라서 Collection에서의 데이터는 Object 타입의 객체로서 저장이 되는 것인데, 그렇다면 여기서 기본 데이터형은 어떻게 저장하고 관리할 수 있을까?

    기본 데이터형인 5를 Wrapper클래스의 Integer 타입 객체로 변환하여 autoboxing으로 저장할 수 있다. 즉, 오토박싱을 통해 기본 데이터형을 컬렉션에 직접 대입하여 저장해도 컴파일러가 자동으로 Wrapper 클래스로 변환해준다

    저장된 값을 얻어올 때에도 객체화된 데이터를 기본 데이터형으로 바로 얻어올 수 있는 데, 이 경우 언박싱(unboxing)이라는 용어를 사용한다.


    List : Interface

    • 동일한 데이터의 중복을 허용한다.
    • 데이터 저장 순서가 유지된다
    • 힙 영역 내에서 List는 객체를 일렬로 늘어 놓은 구조를 취한다.
    • 객체를 인덱스로 관리하기 때문에 객체를 저장하면 자동으로 인덱스가 부여되고, 인덱스로 객체를 검색 및 삭제할 수 있다.
    • 이 때 List는 객체 자체를 저장하여 인덱스를 부여하는 것이 아니라, 해당하는 인덱스에 객체의 주소값을 저장한다.
    • 추가, 검색, 삭제 메소드를 갖고 있다.

    ArrayList

    ArrayList는 List 인터페이스의 구현 클래스로, 데이터(객체)는 인덱스로 관리된다.

    Array List는 배열로 구현한 리스트이다. 내부에서 배열을 이용하기 때문에 인덱스를 이용해서 데이터에 접근합니다. 데이터를 조회할 땐 빠르지만, 데이터를 추가/삭제할 땐 느립니다.

    • 기본 생성자로 ArrayList 객체를 생성하면, 내부에 10개의 객체를 저장할 수 있는 초기 용량을 가지게 된다.
    • 만약 arrayList.add("more"); 로 1개의 객체를 추가하면, 즉 저장 용량을 초과한 객체들이 들어오면 arrayList가 참조하고 있는 ArrayList 컬렉션에는 10*2+2 = 22개의 객체를 저장할 수 있는 공간이 자동으로 생겨난다.
    • Array로 구현한 리스트는 데이터를 매우 빠르게 가져옵니다. 메모리 주소를 정확하게 참조해서 데이터를 가져오기 때문이죠.

    ArrayList 의 단점

    • 위에서 언급한 Size 확장 문제는 ArrayList의 단점이다.
    • Size를 늘리는 과정에서 많은 시간이 소요된다는 점이다.
    • Size 부족으로 이를 확장하게 되는 경우, 기존의 ArrayList에 데이터를 추가하는 것이 아닌, 확장된 크기의 ArrayList를 새로 생성한다.
    • 새로 생성한 ArrayList에 기존 ArrayList의 값들을 복사해주는 과정을 거친다.
    • 그리고 기존의 ArrayList는 GC에 의해 메모리에서 제거된다.
    • 따라서 ArrayList의 Size를 늘린다는 것은 새로운 배열 인스턴스의 생성과 기존 데이터의 복사가 필요한 번거로운 작업이 되는 것이다.

    Vector

    Vector는 ArrayList와 동일한 내부 구조를 가지고 있다.

    ArrayList와 다르게 Vector는 동기화된 메서드로 구성되어 있기 때문에 멀티 스레드가 동시에 이 메서드를 실행할 수 없고, 하나의 스레드가 실행을 완료해야만 다른 스레드가 실행할 수 있다.

    따라서 멀티 스레드 환경에서 안전하게 객체를 추가, 삭제할 수 있다.


    LinkedList

    LinkedList는 List의 구현 클래스이므로 ArrayList와 사용하는 메소드는 같지만 내부구조는 완전 다르다. ArrayList는 내부에 배열 객체를 저장해서 인덱스로 관리하지만, LinkedList는 양방향 포인터 구조로, 데이터마다 인접하는 주소값을 이용하여 체인처럼 관리한다.

    따라서 LinkedList는 특정 인덱스의 객체를 제거하거나 삽입하면, 앞 뒤 링크만 변경되고 나머지 링크는 변경되지 않는다. 그러므로 삽입/삭제가 빈번할 수록 LinkedList를 쓰는 것이 효율적이다.

    반대로 순차적인 삽입/삭제가 빈번하다면 ArrayList를 사용하는 것이 효율적이다.


    Set : Interface

    • 데이터의 저장 순서를 유지하지 않는다.
    • 같은 데이터의 중복 저장을 허용하지 않는다.
    • 인덱스로 조회할 수 있는 메서드가 없다.
    • 대신 전체 객체를 대상으로 하나씩 조회할 수 있는 Iterator 를 제공.

    HashSet

    • 순서가 필요없는 데이터를 해쉬테이블에 저장. Set 중에서 가장 성능이 좋다.
      • 별도의 정렬작업이 없기 때문이라고 한다.
    • HashSet에 이미 존재하고 있는 데이터를 추가하려고 하면, 해당하는 요소를 바로 저장하지 않고, 내부적으로 객체의 hashCode()메서드와 equals() 메서드를 호출하여 검사한다.

    TreeSet

    • 저장된 데이터의 값에 따라 정렬됨. red-black 트리 타입으로 값이 저장됨.
    • HashSet보다 성능이 느림

    LinkedHashSet

    • 연결된 목록 타입으로 구현된 Hash Table에 데이터 저장
    • 저장된 순서에 따라 값이 전렬되나 Set 중에 가장 느림


    해시 알고리즘: Hash Algorithm

    해시 알고리즘이란 해시 함수를 사용하여 해시 테이블에 저장하고, 다시 그것을 검색하는 알고리즘이다.

    자바에서 해시 알고리즘을 이용한 자료구조는 위의 그림과 같이 배열과 연결리스트로 구성된다.

    저장할 Key값과 Value를 넣으면 해시함수는 int index = key.hashCode() % capacity 연산으로 배열의 인덱스를 구하여 해당 인덱스에 저장된 연결 리스트에 데이터를 저장하게 된다.


    Map : Interface

    Map은 key-value 쌍으로 구성된 Entry 객체를 저장하는 구조를 가지고 있다. value는 중복 저장이 가능하지만 key는 중복저장이 불가능하다.

    Set과 마찬가지로, Map 컬렉션에서는 Key 값의 중복저장이 허용되지 않는다.

    만약 중복 저장을 한다면, 기존 값은 없어지고 새로운 값으로 대체한다.


    HashMap

    HashMap은 Map 인터페이스 구현을 위해 해시테이블을 사용한 클래스이다.

    중복을 허용하지 않고, 순서를 보장하지 않는다.

    key value 값으로 null 이 허용된다.






    'Computer Science' 카테고리의 다른 글

    -  (0) 2020.12.30
    Array & List  (0) 2020.12.23
    JVM 이해  (0) 2020.12.19
    의존성 주입(Dependecy Injection) 이란?  (0) 2020.12.17
    커널(Kernel)  (0) 2020.12.09
Designed by Tistory.