728x90
배열
- array.indices는 0부터 마지막 index까지의 range이다.
- withIndex()를 사용하면, 인덱스와 값을 한번에 가져올 수 있다.
- array.plus()를 이용하면, 값을 쉽게 넣을 수도 있다.
val arr = arrayOf(100, 200)
arr.plus(300) // 배열에 새로운 element 추가
// 방법 1
for (i in arr.indices) {
println("$i ${arr[i]}")
}
// 방법 2
for ((idx, value) in arr.withIndex()) {
println("$idx $value")
}
Collection - List, Set, Map
- 컬렉션을 만들어줄 때, 불변인지 혹은 가변인지를 설정해야 한다.
- 가변(Mutable) 컬렉션: 컬렉션에 element를 추가, 삭제할 수 있다.
- MutableList: 기본 구현체는 ArrayList이고, 기타 사용법은 자바와 동일하다.
- MutableSet, MutableMap
- 불변 컬렉션: 컬렉션에 element를 추가, 삭제할 수 없다.
- List, Set, Map
- Collection을 만들자마자 Collections.unmodifiableList() 등을 붙여준다.
- 불변 컬렉션이라고 하더라도 Reference type인 element의 필드는 바꿀 수 있다.
- 우선 불변 리스트를 만들고, 꼭 필요한 경우 가변 리스트로 바꾼다.
🔎 List
- 가변 집합의 기본 구현체는 ArrayList이다.
// val numbers = listOf(100, 200) // 불변 리스트
val numbers = mutableListOf(100, 200)
numbers.add(300)
val emptyList = emptyList<Int>()
useNumbers(emptyList()) // 타입 추론 가능시, 생략 가능
// 하나 가져오기
println(numbers[0])
// for each
for (number in numbers) {
println("number = $number")
}
// 전통적인 for문
for ((index, value) in numbers.withIndex()) {
println("index, value = $index, $value")
}
🔎 Set
- 집합은 List와 다르게 순서가 없고, 같은 elemetn는 하나만 존재할 수 있다. (자료구조)
- 가변 집합의 기본 구현체는 LinkedHashSet이다.
// val numbers = setOf(100, 200) // 불변
val numbers = mutableSetOf(100, 200) // 가변
// For Each
for (number in numbers) {
println("number = $number")
}
// 전통적인 for문
for ((index, number) in numbers.withIndex()) {
println("$index $number")
}
🔎 Map
- 가변 Map을 사용하면 (key, value)를 넣을 수 있다.
- 값을 넣을때는 자바처럼 put을 쓸 수도 있고, map[key] = value를 쓸 수도 있다.
- 정적 팩토리 메서드 사용
- 중위 호출
- mapOf(key to value)를 사용해 불변 map을 만들 수 있다.
// JDK 8까지
Map<Integer, String> map = new HashMap<>();
map.put(1, "MONDAY");
map.put(2, "TUESDAY");
// JDK 9부터
Map.of(1, "MONDAY", 2, "TUESDAY");
for (Integer key : map.keySet()) {
System.out.println(key + " " + map.get(key));
}
for (Map.Entry<Integer, String> entry : map.entrySet()) {
System.out.println(entry.getKey() + " " + entry.getValue());
}
val map = mutableMapOf<Int, String>()
map.put(1, "MONDAY")
map.put(2, "TUESDAY")
// map[1] = "MONDAY"
// map[2] = "TUESDAY"
mapOf(1 to "MONDAY", 2 to "TUESDAY")
for (key in map.keys) {
println("$key ${map[key]}")
}
for ((key, value) in map.entries) {
println("$key $value")
}
Collection의 null 가능성, 자바와 함께 사용하기
- ? 위치에 따라서 null 가능성 의미가 달라지므로 차이를 잘 이해해야 한다.
- List<Int?> : 리스트에 null이 들어갈 수 있지만, 리스트는 null 이 아니다.
- List<Int?>? : 리스트에 null이 들어갈 수 있고, 리스트가 null일 수 있음
- List<Int>? : 리스트에는 null이 들어갈 수 없지만, 리스트는 null 일 수 있음
- 자바와 함께 사용시
- 자바는 읽기 전용 컬렉션과 변견 가능 컬렉션을 구분하지 않는다.
- 자바는 nullable 타입과 non-nullable 타입을 구분하지 않는다.
- 따라서 코틀린 쪽의 컬렉션이 자바에서 호출되면 컬렉션 내용이 변할 수 있음을 감안해야 한다.
- 필자가 자바에서 코틀린 리스트를 사용했을 때는 불변일시에는 값 추가는 안되었다.
- 또는 코틀린 쪽에서 Collections.unmodifableXXX() 를 활용하면 변경 자체를 막을 수 있다.
class ListWithJava() {
val list = listOf(100, 200)
val unmodifiableList = Collections.unmodifiableList(list)
val modifiableList = mutableListOf(100, 200)
}
ListWithJava listWithJava = new ListWithJava();
List<Integer> unmodifiableList = listWithJava.getUnmodifiableList();
unmodifiableList.add(300);
for (Integer integer : unmodifiableList) {
System.out.println("integer = " + integer);
}
- 또한 코틀린에서 자바 컬렉션을 가져다 사용할 때는 플랫폼 타입을 신경써야 한다.
- 자바에서 List<Integer>를 줄 때, 코틀린에서는 List<Int?>, List<Int?>?, List<Int>? 인지 모른다.
- 따라서 자바 코드를 보며 맥락을 확인해야 하고, 자바 코드를 가져오는 지점을 wrapping 해야한다.
728x90
'Language > kotlin' 카테고리의 다른 글
다양한 함수 다루기 (0) | 2023.05.24 |
---|---|
Enum, Sealed Class - 공통점, 차이점 정리 (0) | 2023.05.23 |
다양한 클래스 다루기 (0) | 2023.05.23 |
중첩 클래스 다루기 (0) | 2023.05.22 |
object 키워드 다루기 (0) | 2023.05.22 |