Collection에대하여
java와 kotlin의 Collection에 대하여 알아보겠습니다.
자료구조 상속,구현도
1 . 다른 언어와 달리 kotlin에서는 변경가능하고 변경 불가능한 콜렉션(list, set, map)을 구분합니다.
예를들어 Kotlin의 List<out T>유형은 읽기 전용의 작업을 제공하는 인터페이스입니다. size와 get등의 함수가 내장되어있습니다. 자바와 마찬가지로 Collection<T>를 상속하며 , Iterable<T>도 상속합니다.
목록을 변경하려면 MutableList<T>인터페이스를 이용해 추가할수 있습니다 .
이는 Set<out T>/ MutableSet<T>및 Map<K, out V>/MutableMap<K, V>도 동일합니다
ex)
val mutableMap = mutableMapOf() //변경 가능한 map
2. List(ArrayList, LinkedList)
list는 순서를 중요하게 여기는 자료구조입니다
arrayList는 List<T>의 하위 유형이라고 정의할 수 있습니다.
List와 ArrayList의 유사점
둘 다 초기화 이후에 요소를 추가할 수 없습니다. (immutable입니다)
list.add("dog") // cannot be expanded or shrank
둘 다 일반적으로 컬렉션이라고 하는 여러 요소를 저장하는 데 사용되는 컨테이너입니다.
val list = listOf("apple", "ball", "cow")
// List에는 intListOf, charListOf가 없으므로 기본 배열에 최적화되어 있지 않습니다.
- Array<TYPE>은 정해진 구현을 가진 클래스입니다. 항목을 저장하는 연속된 고정 크기 메모리 영역입니다.
- List<T> 및 MutableList<T>는 다른 구현을 가지는 인터페이스입니다.
각각의 데이터는 각각의 node란 곳에 저장이 됩니다.
node는 두 부분으로 나뉘어져 있는데
한곳은 데이터를 저장하고, 다른 한곳은 다음 노드의 주소를 참조합니다.
node A는 ‘내 다음 node는 B다!’ 라는 건 알지만
C나 D의 위치, 존재여부도 모릅니다.
배열과 비슷하지만, 메모리 관리 측면에서 좀 더 효율적입니다.
예를 들어 크기 5의 배열이 있다고 가정하겠습니다.
1번째 위치의 값이 삭제된다면 2, 3, 4번째 위치의 값은
하나씩 앞으로 당겨져야 합니다.
LinkedList의 경우를 살펴보겠습니다.
5개의 값이 있는 LinkedList 객체가 있습니다.
0번째 노드는 1번째 노드를 참조하고, 1번쨰 노드는 2번째 노드는 참조하겠죠.
이 상황에서 1번째 노드를 삭제하면 2, 3, 4번째 노드의 위치가 다 옮겨지는게 아닙니다.
그냥 0번째 노드가 참조하는 노드를 2번째 노드로 설정하면 끝입니다.
즉, 중간에 있는 값이 삭제되거나 추가되는 상황에서는
배열보다 LinkedList를 쓰는게 메모리 관리 측면에서 더 효율적입니다.
자바에서 LinkedList 클래스를 살펴보겠습니다.
지금은 Queue를 구현하는데 사용하고 있지만 List도 구현하는 걸 확인할 수 있습니다.
LinkedList 클래스의 생성자를 살펴보겠습니다.
LinkedList는 객체 생성시 크기를 지정하지 않는 걸 볼 수 있습니다.(empty list)
각 데이터들이 앞뒤로 연결되는 구조이기 때문에 미리 공간을 만들어 놓을 필요가 없습니다.
API 문서에서 LinkedList의 메소드를 살펴보면
여러 인터페이스를 구현한 만큼 메소드도 많습니다.
그런데 자세히 살펴보면 중복된 기능을 가진 메소드들이 많습니다.
예를 들어 add(), addLast(), offer(), offerLast()
이 4개의 메소드들은 모두 LinkedList 객체 가장 뒤에 값을 추가하는 역할을 합니다.
이렇게 중복된 메소드들이 많은 이유는 마찬가지로 여러 인터페이스를 구현했기 때문입니다.
저 메소드를 섞어서 쓰면 보는 사람은 더 혼동될 것이기 때문에
하나를 정해서 그것만 쓰는게 좋습니다.
저는 addLast()가 가장 명확하게 기능을 말해주고 있는거 같아 맘에 드네요
클래스 |
특징 |
HashSet |
순서가 필요없는 데이터를 hashTable에 저장. Set중에 성능 가장 좋음 |
TreeSet |
저장된 데이터의 값에 따라 정렬됨. red-black tree 타입으로 값이 저장. HashSet보다 성능이 느림 |
LinkedHashSet |
연결된 목록 타입으로 구현된 hash table에 데이터 저장. 저장된 순서에 따라 값이 정렬. 셋중 가장 느림 |
위 3개의 클래스들이 성능 차이가 나는 이유는 데이터 정렬 때문입니다.
HashSet은 별도의 정렬작업을안해 가장 빠릅니다.
먼저 HashSet의 상속관계를 살펴보겠습니다.
AbstractCollection을 확장한 건 ArrayList와 같지만,
HashSet은 AbstractSet을 확장했습니다.
AbstractSet 문서에 들어가보면 구현되어 있는 메소드는
equals(), hashCode(), removeAll() 3개 뿐입니다.
Set은 순서가 필요없고, 중복을 허용하지 않으므로
중복을 체크하는 equals()와 hashCode()는 필수인거 같습니다
HashSet의 생성자
HashSet의 메소드
순서가 필요없어서 그런지 메소드가 적습니다.
4. Map(HashMap, TreeMap)
map은 'Key-Value' pair 형식으로 데이터를 저장합니다. key와 value는 매치되어있습니다.
Map의 메소드를 찾아보면 다음과 같습니다.
이 중 가장 많이 쓰이는 건 put(), get(), remove()입니다.
map을 구현하고 있는 클래스는 HashMap, TreeMap, LinkedHashMap 입니다.
HashMap
HashMap 은 요소가 Map에 배열되는 값들의 순서를 보장하지 않습니다 .
즉, HashMap 의 키 와 값 을 반복하면서 순서를 지정할 수는 없습니다 .
@Test
public
void
whenInsertObjectsHashMap_thenRandomOrder() {
Map<Integer, String> hashmap =
new
HashMap<>();
hashmap.put(
3
,
"TreeMap"
);
hashmap.put(
2
,
"vs"
);
hashmap.put(
1
,
"HashMap"
);
assertThat(hashmap.keySet(), containsInAnyOrder(
1
,
2
,
3
));
}
TreeMap
자연 순서에 따라 정렬 .
TreeMap 객체를 자연 순서에 따라 소트 할 수없는 경우 , Comparator 또는 Comparable 를 사용해, 요소가 맵 내에 배치되는 순서를 정의 할 수 있습니다 .
@Test
public
void
whenInsertObjectsTreeMap_thenNaturalOrder() {
Map<Integer, String> treemap =
new
TreeMap<>();
treemap.put(
3
,
"TreeMap"
);
treemap.put(
2
,
"vs"
);
treemap.put(
1
,
"HashMap"
);
assertThat(treemap.keySet(), contains(
1
,
2
,
3
));
}
HashMap과 TreeMap의 차이
HashMap 은 하나의 null 키 와 많은 null 값을 저장할 수 있습니다 .
예를 들어 보겠습니다.
@Test
public
void
whenInsertNullInHashMap_thenInsertsNull() {
Map<Integer, String> hashmap =
new
HashMap<>();
hashmap.put(
null
,
null
);
assertNull(hashmap.get(
null
));
}
널 키가 있기 때문에 허용되지 않습니다 은 compareTo () 또는 비교 () 메소드는 발생 NullPointerException가 :
@Test
(expected = NullPointerException.
class
)
public
void
whenInsertNullInTreeMap_thenException() {
Map<Integer, String> treemap =
new
TreeMap<>();
treemap.put(
null
,
"NullPointerException"
);
}
|
'Kotlin' 카테고리의 다른 글
Collection에 대하여 -3 collection에 적용할수 있는 함수들 (4) | 2019.03.09 |
---|---|
Collection에 대하여 -2 collection에 적용할수 있는 함수들 (2) | 2019.03.09 |
Kotlin - inline, noinline, clossline, reified (4) | 2019.03.09 |
Kotlin List, Map (4) | 2019.01.23 |
Kotlin enum과 when (4) | 2019.01.23 |
댓글