생각을 개발하자, 박진형

[Java] 자료구조 API - 컬렉션프레임워크 본문

Java/java basic

[Java] 자료구조 API - 컬렉션프레임워크

imjinbro imjinbro 2017.11.08 01:42

[샘플코드]

https://github.com/imjinbro/javaBasic/tree/master/src/com/jinbro/source/collection



[컬렉션 프레임워크]

- 객체 자료구조를 API 제공함 : 인터페이스와 인터페이스 구현 클래스 제공

- 주요 인터페이스

1) List : 선형자료구조(순서O), 중복O

2) Set : 순서X, 중복X

3) Map : key-value 쌍으로 저장, 순서X, key 중복되면 X / value 중복되어도 상관X

0) Collection 인터페이스 > List, Set : List Set Collection으로 묶임

- 같은 메서드가 많으니 하나의 타입(Collection)으로 묶음 : 타입에 대한 의미랄까

- 제네릭 사용 : 타입인자 넘겨주지않으면 기본적으로 Object 타입, 캐스팅/안전성을 위해서 사용하는 것이



[List]

1) 선형으로 자료(객체) 저장, 객체 참조값(메모리주소, null 저장할 경우 없는 것으로) 저장함

2) List<E> 구현 객체

- ArrayList<E>

(1) 내부적으로 배열을 사용하고, 최초 크기 초과할 경우 크기의 새로운 배열을 생성함(비효율적일 때가)

(2) 중간 삭제, 추가 밀고 당기기를 구현하지않아도 알아서 해줌 : 그러나 비효율적이라는

(3) 검색과 마지막 추가라면 LinkedList 보다 효율적 : 인덱스 검색, 배열 마지막 인덱스에 저장만 해주면되니깐


- Vector<E>

(1) ArrayList 동일한 내부구조

(2) 차이점 : synchronized 처리된 메서드 - 쓰레드 세이프(멀티쓰레드 공유객체에 접근 먼저 접근한 객체에 접근권한)


- LinkedList<E>

(1) List 구현한 객체지만 ArrayList/Vector와는 전혀 다른 내부구조

(2) 노드(데이터를 저장한 객체) 연결한 형태 : 객체 간의 연결

(3) 중간 삭제, 추가 작업을 하더라도 인덱스를 뒤로 밀거나 앞당기거나 하지않고 연결된 부분만 끊음

- 잦은 삽입/삭제 작업에는 효율적 : 특히 중간작업

- 탐색 작업에는 상대적으로 비효율적 : 연결된 형태여서 하나씩 타고 넘어가면서 맞는지 확인



[Set]

1) 순서 유지(in-out 순서 다름)없고 객체 중복 저장X : 주머니에 넣어놓은 것과 같음

2) List 달리 index 관리하지않음 : 객체 비교를 통해 동일한 것이 있는지 삭제할건지 명령

3) Set<E> 구현객체

- HashSet

(1) 동일한 객체 저장X

(2) hashCode() : 저장하려는객체.hashCode() 호출 결과와 저장되어있는객체.hashCode() 비교

(3) equals() : hashCode 비교 결과 동일한 해시코드가 있다면 equals 비교함(true 경우 저장X)

(4) String : 같은 문자열인 경우 hashCode 동일한 해시코드, equals true 나오도록 오버라이딩 해놓음

(5) 내부적으로 HashMap 사용 : 데이터를 key 저장

(6) 동기화X


- LinkedHashSet

- TreeSet

(1) 이진트리 : 계층관계 표현(자동 정렬), 일렬로된 자료구조보다 빠른 탐색 속도(O(lgN) 정도)

(2) TreeSet 가진 메서드를 사용하기위해 인스턴스 주소값을 TreeSet 타입 변수에 저장해야

(3) 오름차순 정렬(기본)

- 객체에 Comparable 구현하거나 따로 Comparator 구현 객체를 만들어야함

- 내림차순 정렬된 TreeSet 반환받을 있는 메서드가 있음 : 리턴타입은 NavigableSet<T>

- 내림차순 정렬 Iterator 리턴받을 있음


(4) 정렬 - 검색에 특화되어있음 : 관련 메서드가 많음



[Iterator : Collection 인터페이스 구현객체만 - List, Set]

1) 자료구조에 저장된 데이터(객체) 가져오는 표준 방법

- 저장되어있는 객체를 하나씩 가져올 있음, 여러 메서드들을 제공함

- Collection 구현객체의 iterator, listIterator 메서드로 Iterator 객체를 얻을 있음 : 메서드 사용

- ForEach 간단하게 루프돌릴 있음 : Collection<T> 파라미터로 설정한 forEach 내장 메서드


2) Collection Interface(타입) 구현 객체만 사용할 있음 : 같은 기능을 하는...묶음

- List

- Set


3) Iterator 메서드만 사용할 것이라면 ? 와일드카드를 사용하면

- 타입이 그렇게 중요하지않다면



[Comparable, Comparator]

1) 레퍼런스 타입 정렬 기준 구현 메서드 제공 인터페이스

- compareTo(Object o) : Comparable

- compare(Object o1, Object o2) : Comparator


2) TreeSet, TreeMap 경우는 반드시 구현한 객체를 타입파라미터로



[Map]

1) 순서유지X, key-value( 객체)쌍으로 저장, key 중복되면 안됨

2) 제네릭 타입 : Map 인스턴스 생성할 타입 인자를 받아서 지정

3) key - value 목록을 얻는 방법은 예제 코드에

4) Map<E> 구현객체

- HashMap

(1) key : hashCode, equals 같은 key인지 확인, 주로 String 사용

(2) Entry : 저장된 단위로 보면


- HashTable

(1) HashMap 동일하지만 ArrayList - Vector처럼 메서드 동기화 지원 여부 차이

(2) 멀티쓰레드 환경에서는 HashTable 사용


- Properties

(1) HashTable 하위 클래스 : HashTable<String,String> 버젼이라고 있음

(2) K,V String으로 제한함 : 제네릭타입이 아니라 String 고정

(3) 유일 key 대한 정보를 저장 -> 옵션정보, db 연결정보, 다국어 정보 파일(프로퍼티 파일) 읽어볼 사용한다고함

- 프로퍼티파일(.properties) : = 으로 구성, 한글은 유니코드로 변환 저장, 사용하는 클래스와 같은 경로에 저장


(4) Properties 메서드가 많아서 Map 타입으로 변수 선언하지않고 Properties 선언하는게


- LinkedHashMap

- TreeMap

(1) 이진트리기반 Map : key-value(Map.Entry) 같이 저장

(2) key 기준으로 정렬

- key 사용할 객체에 Comparable 구현하거나 따로 Comparator 구현 객체를 만들어야함



(3) Set<Map.Entry<T,R> val> 목록 얻기위해서



[Stack]

1) 선입후출 구조 : 먼저 들어온 것이 가장 늦게 나감

2) 스택의 위와같은 특징을 활용하면 가장 뒤에 입력된 것이나 가장 가까운 것을 찾아내기가 쉬움

3) JVM 스택메모리가 대표적인

4) Vector 상속 클래스 : synchronized 메서드 - pop, peek, search



[Queue]

1) 선입선출 구조 : 먼저 들어온 것이 먼저 나가는 특징을 가짐

2) 쓰레드풀의 작업 : Runnable, Callable 객체를 저장해뒀다가 쓰레드에 저장된 순서대로 바인딩해서 작업처리

3) Queue 인터페이스 : 큐를 구현한 대표적인 클래스가 링크드리스트(Collection > List - LinkedList)



[동기화 컬렉션 : 동기화메서드 사용]

- 멀티쓰레딩 환경에서 synchronized 매우 중요

- 싱글쓰레드 처리를 하는데에도 동기화 메서드를 사용한다면 낭비


1) Vector(synchronized ArrayList), HashTable(synchronized HashMap)

2) 나머지 컬렉션의 메서드를 동기화 메서드로 래핑하는 방법

- Collections.synchronizedXXX : 컬렉션프레임워크 유틸리티 클래스

- XXX : List / Set / Map



[부분잠금 컬렉션 : 병렬처리, 동기화블록 사용]

- 동기화를 메서드로 지정하지않고 필요한 부분만 동기화 영역으로 처리해서 조금 효율적인 처리를 있도록

- 메서드 처리 동기화 부분이 필요한 부분만 블록처리한 컬렉션