8. 추상 클래스 Abstract Class
• 인스턴스화 될 수 없다.
• 클래스를 통해 상속할 수 있다.
• 추상 메소드는 구현부 없이 정의된 메소드이다
• abstract method를 포함한 클래스는 abstract로 정의되어야 한
다.
• Abstract class를 상속한 클래스는 abstract method의 구현부를
제공해야 한다. 그렇지 않으면, 자식 클래스도 abstract로 정의
되어야 한다.
9. Abstract Class vs Interface
• 공통점
• 인스턴스화 할 수 없다.
• 구현부 없는 메소드들을 정의할 수 있다.
• 차이점
• Abstract class
• Non-static, final 필드 정의 가능
• Public, protected, private concrete method 작성 가능
• 한 클래스만 상속 가능하다.
• Interface
• 모든 요소들의 접근 제어자가 public이다.
• 여러 인터페이스를 한번에 구현할 수 있다.
10. 언제 어떤것을 써야 하나요?
• 추상 클래스를 고려해야 하는 상황
• 긴밀하게 연결된 클래스들 간 코드를 공유하고 싶다.
• Abstract class를 상속받는 클래스들이 공통적인 메소드, 필드, public외의 다른 접근자가 필요하다고
예측할 경우
• non-static 이나 non-final 필드를 정의하고 싶을 경우.
• 인터페이스 사용을 고려해야 하는 상황
• 관계없는 클래스들도 당신의 인터페이스를 구현할 수 있다. 예를 들어, Comparable 과 Clonable
interface는 많은 관계없는 클래스들이 구현하고 있다.
• 특정 데이터 타입의 행동을 특정하고 싶을 때. 하지만 누가 행동을 구현하는지는 중요하게 생각하지
않을 때.
• 여러 개의 상속을 통한 이득을 얻고 싶을 때.
11. Generics
• 클래스, 인터페이스, 메소드를 정의 할 때 타입을 파라미터화 할
수 있게 만든다.
• 일반적인 paramter처럼, 다양한 입력들에 대해 같은 코드를 사
용할 수 있게 만들어준다.
• 일반적인 parameter에서는 입력이 값이고, Generics에서는 입
력이 type이다.
13. Generics 장점
• 컴파일 단계에서 타입 체크를 강하게 한다.
자바 컴파일러는 제네릭 코드에 대해 강하게 타입 체크를 하고 type safet를 충족하지 못하면 에러를 냅니다. 런타임 에
러는 찾기 어려울 수 있기 때문에 컴파일중 에러를 고치는 것이 더 수월합니다.
• 캐스팅을 없앨 수 있습니다.
• Generics를 쓰지 않는 코드:
• List list = new ArrayList();
list.add("hello");
String s = (String) list.get(0);
• Generics를 쓴 코드:
• List<String> list = new ArrayList<String>();
• List.add("hello");
• String s = list.get(0); // no cast
• 프로그래머가 일반적인 알고리즘을 구현할 수 있게 합니다.
타입별로 다른 알고리즘을 구현하지 않아도 되고, type safe하고 읽기 쉽습니다.
15. Diamond operator
• 컴파일러가 Type를 결정할 수 있을 때 <>만 써줘도 된다.
• JDK 7 이후부터 지원
• List<String> list = new ArrayList<String>(c);
List<String> list = new ArrayList<>(c);
16. Java Collections Framework란?
• 자바 플랫폼에 포함된 프레임워크
• Collection?
• 여러 요소를 한 단위로 묶은 것
• 객체들의 그룹을 표현한 객체
• JCF는 collection을 표현하고 조작하는 것들을 통합한 아키텍처
17. 구성 요소들
• Collection 인터페이스. Collection들의 형태를 표현한다. 프레임워크의 기반을 형성하고 있다. Ex) sets, lists, maps.
• 일반적인 목적의 구현. 인터페이스들의 주요한 구현
• 알고리즘. Sorting같은 유용한 static 함수들
• 특별한 목적을 위한 구현
• 비동기 처리를 위한 구현
• Wrapper 구현. Synchronization 등의 구현을 더하는 기능
• 편리함을 위한 구현
• Abstract 구현. Cutsom Collection을 지원하기 위한 목적
• Infrastructure. Collection 인터페이스를 지원하는 필수적인 인터페이스들. Ex) Iterator, Comparable, …
• Array 유틸리티.
18. Advantages
• 프로그래밍 수고를 덜어줍니다.
자료구조나 알고리즘을 직접 작성하지 않아도 됩니다.
• 퍼포먼스를 향상시킵니다.
인터페이스간 다양한 구현들을 교체할 수 있기 때문에 구현을 프로그램을 튜닝하기 용이합니다.
• 관계없는 API간 상호 정보교환이 가능하도록 만듭니다.
• API를 배우는 수고를 덜어줍니다.
이전에는 API마다 각자 본인들의 collection을 사용해 익히기 어려웠습니다.
• 위와 같은 이유로, API를 디자인하는 수고를 들여줍니다.
Collection을 만들도 되지 않기 때문입니다.
• 소프트웨어 재사용성을 높입니다.
25. Vector & Stack – 권장하지 않는 이유
• 자바 1.0부터 이어져 왔지만 1.2버전부터 사용하지 않게 됨
• Vector
• 각 연산에 대해서 동기화 처리를 한다. -> 단일 스레드에서도 동기화 처리를 계속 한다.
• 퍼포먼스가 매우 안좋음
• 동기화 처리를 원한다면 SynchronizedList로 대체
• 동기화 처리를 원하지 않는다면 ArrayList로 대체
• Stack
• 위와 같은 이유로 퍼포먼스가 매우 안좋음
• 동기화 처리를 원한다면 SynchronizedStack으로 대체
• 동기화 처리를 원하지 않는다면 ArrayDeque으로 대체
27. List
• 순서가 있는 Collection
• 중복 요소를 가질 수 있음
• Collection에 더해 인터페이스에 포함된 기능들
• 위치로 접근 가능 – 숫자 위치에 기반하여 요소를 조작할 수 있음. Get, set,
add, addAll, remove.
• 검색 — 특정 객체를 검색하여 위치를 반환. indexOf, lastIndexOf.
• listIterator – 순서가 있다는 성질을 이용해 기존 iterator보다 많은 기능을 사
용 할 수 있습니다. 거꾸로 iterate, 특정 위치의 iterator 획득 등등.
• 범위 — sublist 관련한 method
31. ArrayList
• Array를 기반으로 List interface 구현.
• List의 모든 Optional 기능들을 구현. null을 포함해 모든 요소들을 허용한다.
• 연산들의 속도가 LinkedList보다 대부분 빠릅니다.
• Capacity : ArrayList 내부 배열의 크기
Size : ArrayList가 가지고 있는 요소들의 개수
Capacity는 최소 size만큼의 크기를 가지고 있습니다.
• ArrayList에 Capacity를 넘는 양의 데이터가 들어오면, 2배 크기의 배열을 만들고
값을 복사해 Capacity를 2배로 늘립니다.
36. PriorityQueue
• 힙 기반으로 구현된 우선순위 큐
• *natural ordering을 사용하기 때문에 non-comparable한 객체들은 삽입할 수 없다.
• Natrual ordering – Comparable 인터페이스 구현을 통해 순서를 정하는 방식
• 또는 PriorityQueue가 생성될 때 Comparator를 통해 순서 방식을 정해줄 수 있습니다.
• Queue의 헤드는 특정 순서법에 따른 최소값입니다. 최소값을 가진 요소가 여러가지라면, 그 중에 하나가 헤드가 됩니
다.
• 우선순위 큐는 크기 제한이 없습니다. ArrayList와 같이 Capacity는 내부적으로 저장하고 있는 배열의 크기이고, size는
담고 있는 요소들의 개수입니다. Element가 더해지면 capacity는 자동으로 커집니다. 크기가 커지는 정책은 정해져있지
않습니다.
• Collection과 Iterator 인터페이스의 메소드(optional 포함)들을 전부 구현하고 있습니다.
• 이 클래스에서 제공되는 iterator는 순서를 보장하지 않습니다. 만약 정렬된 상태를 원한다면 Arrays.sort(pq.toArray())
를 고려해야 합니다.
39. Deque
• Double ended queue
• 크기를 제한할 수 있다.
• 양 끝에서 요소에 접근할 수 있는 메소드들이 정의되어 있다.
• 용량이 제한된 덱을 위해 operation이 실패하면 special value를
리턴하는 형태의 메소드가 구현되어 있다.
40. The twelve methods described above are summarized in
the following table:
45. LinkedList
• 이중 연결 리스트 기반으로 List와 Deque을 구현
• 모든 optional 메소드들을 구현했다.
• Null을 포함해 모든 요소들을 허용한다.
• 이중 연결 리스트의 알고리즘을 사용한다. Index를 통해 접근하
려면 앞이나 뒤에서 차례차례 접근해 나가야 한다.
• 대부분 경우 효율이 좋지 않다. 정말 특정한 상황에서만 사용하
는 것을 권장
48. Map
• 키와 값를 매핑해주는 것
• 중복 키를 가질 수 없음.
• 각 키는 하나의 값만 가질 수 있음
• 기본적인 연산들 – put, get, remove, containsKey,
containsValue, size, empty
• 묶음(bulk) 연산들 – putAll, clear
• Collection Views – keySet, entrySet, values
49. Collection View
• View 는 Java Collections Framework에서 Collection 이나 Map
인터페이스를 구현한 가벼운 객체입니다. 하지만 실제로는
collection은 아닙니다. 사실은, 뷰는 다른 collection, 배열이나
단일 객체를 참조하고 이를 이용해 사용자에게 데이터를 제공
합니다.
52. HashTable – 사용하지 않는 이유
• 자바 1.0부터 이어져 왔지만 1.2버전부터 사용하지 않게 됨
• 각 연산에 대해서 동기화를 한다. -> 단일 스레드에서도 동기화
처리를 계속 한다.
• 퍼포먼스가 매우 안좋음
• 동기화를 원한다면 ConcurrentHashMap로 대체
• 동기화를 원하지 않는다면 HashMap로 대체
55. HashMap
• 해시 테이블 기반으로 맵을 구현
• Optional map 메소드들도 구현
• Null 키와 null 값 허용함.
• 시간이 지남에 따라 순서가 일정하게 유지된다는 것을 보장하
지 않음.
56. HashMap
• Hash function이 적절하게 구현되어 있다는 전제에 한해 Get,
put은 O(1)의 효율을 냅니다.
• Collection View를 Iterate 하는 것은 HashMap의 Capacity와
Key-value 쌍의 개수를 더한 것에 비례합니다.
• Iteration 효율이 중요하다면 초기 용량을 너무 크게 잡지 않아
야 합니다.
58. LinkedHashMap
• HashMap에 더해서 순서를 저장하는 doubly-linked list를 유지
합니다.
• 이 링크드 리스트는 iteration order를 정의하고, 보통은
insertion-order이다.
• HashMap과 같이 iterator를 사용하더라도 LinkedHashMap은
순서를 맞춰 iterator를 반환
60. SortedMap
• 키를 바탕으로 순서를 만드는 맵
• *natural ordering을 사용하기 때문에 non-comparable한 객체들은 삽입할 수 없습니다.
키들은 상호간에 비교가 가능해야 합니다.
• 또는 SortedMap이 생성될 때 Comparator를 통해 순서 방식을 정해줄 수 있습니다.
• 순서는 entrySet, keyset, values 메소드를 통해 반환되는 Collection view들에도 적용됩니
다.
• Key를 이용해 값을 꺼낼 때는 isEqual을 사용하고, 순서를 정할 때는 compareTo를 사용합
니다. 같은 객체에 대헤 isEqual과 comapreTo가 동일하게 계산되도록 주의해야 합니다.
63. NavigableMap
• 검색할 수 있는 Map
• 정확히 같은 객체 뿐 아니라 lower, floor, ceiling, higher로 검색
할 수 있습니다.
• lowerEntry : 제공된 Key보다 작은 최대의 Entry를 반환합니다. 없을 경
우에 null를 반환합니다.
• floorEntry : 제공된 Key와 같거나 작은 Key 중 최대의 Entry를 반환합
니다. 없을 경우에 null를 반환합니다.
• higherEntry, ceilingEntry 는 반대의 동작
66. Red-Black Tree
• 노드는 레드 혹은 블랙 중의 하나이다.
• 루트 노드는 블랙이다.
• 모든 리프 노드는 블랙이다.
• 레드 노드의 자식노드 양쪽은 언제나 모두 블랙이다. (즉, 레드 노드는 연달아 나타날 수 없으며, 블랙 노드만이 레드 노
드의 부모 노드가 될 수 있다)
• 어떤 노드로부터 시작되어 리프 노드에 도달하는 모든 경로에는 리프 노드를 제외하면 모두 같은 개수의 블랙 노드가
있다.
• 위 조건들을 만족하게 되면, 레드-블랙 트리는 가장 중요한 특성을 나타내게 된다: 루트 노드부터 가장 먼 경로까지의
거리가, 가장 가까운 경로까지의 거리의 두 배 보다 항상 작다. 다시 말해서 레드-블랙 트리는 개략적(roughly)으로 균
형이 잡혀 있다(balanced). 따라서, 삽입, 삭제, 검색시 최악의 경우(worst-case)에서의 시간복잡도가 트리의 높이(또는
깊이)에 따라 결정되기 때문에 보통의 이진 탐색 트리에 비해 효율적이라고 할 수 있다.
67. TreeMap
• Red-Black Tree를 기반으로 구현된 NavigableMap.
• Key를 통해 Natural ordering을 하거나, 맵을 생성할때 제공된
Comparator를 이용하여 순서를 정합니다.
69. java.util.Set
• 수학에서의 집합을 모델링
• 중복된 요소를 포함하지 않는 collection
• 정확히는 e1.equals(e2) 를 충족하는 어떤 요소도 포함하지 않는
다.
• Mutable 객체가 Set의 요소로 사용된다면 굉장한 주의를 기울
여야 합니다. Set은 요소의 값이 바뀌어 equals 연산에 영향을
주는 것에 대해 어떤 동작도 하지 않습니다.
72. HashSet
• HashMap 기반으로 구현된 Set
• 시간이 지남에 따라 순서가 일정하게 유지된다는 것을 보장하
지 않음.
• Null 요소 허용
• HashMap 기반이기 때문에 HashMap의 특성을 가집니다. 예를
들어, iteration을 효율적으로 하기 위해서는 capacity 조절해야
합니다.
76. LinkedHashSet
• HashMap에 더해서 순서를 저장하는 이중 연결 리스트를 유지
합니다.
• 이 연결 리스트를 통해 입력된 순서로 iteration order를 정의합
니다.
• 순서에 맞춰 iterator를 반환합니다.
• 추가적으로 구현된 메소드는 없습니다.
78. SortedSet
• 순서가 있는 집합
• *natural ordering을 사용하기 때문에 non-comparable한 객체들은 삽입할 수 없습니다.
키들은 상호간에 비교가 가능해야 합니다.
• 또는 SortedSet가 생성될 때 Comparator를 통해 순서 방식을 정해줄 수 있습니다.
• 순서는 entrySet, keySet and values 메소드를 통해 반환되는 Collection view들에도 적용
됩니다.
• Key를 이용해 값을 꺼낼 때는 isEqual을 사용하고, 순서를 정할 때는 compareTo를 사용합
니다. 같은 객체에 대헤 isEqual과 comapreTo가 동일하게 계산되도록 주의해야 합니다.
81. NavigableSet
• 검색할 수 있는 Set
• 정확히 같은 객체 뿐 아니라 lower, floor, ceiling, higher로 검색
할 수 있습니다.
• lower : 제공된 요소보다 작은 것 중 최대의 요소를 반환합니다. 없을
경우에 null를 반환합니다.
• Floor : 제공된 요소와 같거나 작은 것 중 최대의 요소를 반환합니다. 없
을 경우에 null를 반환합니다.
• higher, ceiling 는 반대의 동작
84. TreeSet
• TreeMap을 기반으로 구현된 Set
• 요소를 통해 Natural ordering을 하거나, Set을 생성할때 제공된
Comparator를 이용하여 순서를 정합니다.
85. Custom Collection 구현
• Custom 구현을 해야할 이유들
• Persistent: ex) 외부 데이터베이스와 직접 연결되는 Collection 등.
• 앱에 특화된 Collection: ex) 전파와 관련된 데이터를 가지는 Map. Key가 위치일때, value는 위치를 이용해 센서에서 읽
어온 전파 값.
• 고효율, 특별한 목적
• 고효율, 일반적인 목적
• 기능 강화: ex) MultiSet – 중복 요소를 허용하는 Set. Suppose you need an efficient bag implementation (also known
as a multiset): a Collection that offers constant-time containment checks while allowing duplicate elements. It's
reasonably straightforward to implement such a collection atop a HashMap.
• 편리성: ex) 특정 범위의 연속되는 자연수를 가진 리스트가 자주 필요할 경우
• Adapter : legacy API를 사용해 Java Collections Framework와 연결해주는 Adapter가 필요할 경우
87. AbstractList
• 수정할 수 없는 리스트를 구현하기 위해서는 이 클래스를 상속
해서 get(int)와 size() 메소드만 구현하면 된다.
• 수정 가능한 리스트를 구현하기 위해선 추가적으로 set(int, E)
메소드를 override 해야 한다.
• 가변적인 크기를 가진 리스트를 구현하기 위해선 add(int, E),
remove(int) 를 추가적으로 구현해야 한다.
• Argument가 없는 생성자를 제공해야 하고, Collection 인터페이
스 명세에 따르는 것을 권장한다.
91. Arrays.asList
• asList는 java.util.ArrayList가 아니라
java.util.Arrays$ArrayList를 반환합니
다.
• Immutable list이고, view의 역할을
합니다 – 값을 복사하지 않습니다.
• 따라서 값을 바꿀일이 없을 때,
asList를 활용하면 더 빠른 효과를
낼 수 있습니다.
92. Google Guava
• Google에서 제공하는 Java library
• 그 중 Collection과 관련된 항목들
• Immutable collection
• New collection types
• Powerful collection utilities
• Extension utilities
93. Immutable collections
• 신뢰할 수 없는 라이브러리로부터 안전하다.
• 쓰레드와 함께 사용하기 안전하다.
• 수정을 제공할 필요가 없어서, 시간과 공간을 절약할 수 있다.
• 상수로 사용할 수 있다.
94.
95. 결론
• 항상 생각없이 ArrayList만 사용했었는데, 좀 더 고민을 하고 자
료구조를 결정하는 것이 좋겠습니다.
• 기회가 되면 Google Guava를 공부해 적용하는 것도 좋을 것 같
습니다.
• immutable 여부를 생각해보기
• Reference Type을 List로 쓰는 등 다형성을 통해 내부 구현을 쉽
게 바꿀수 있도록 코딩 습관을 고쳐야 겠습니다.