Kotlin의 배열과 컬렉션 다루기
배열
- 배열은 잘 사용되지 않는다.
List
사용을 권장함
Java의 배열 사용
1
2
3
4
5
int[] array = {100, 200};
for(int i=0; i<array.length; i++) {
System.out.println("순번 : "+ i + " / 값 : " + array[i]);
}
Kotlin의 배열 사용
1
2
3
4
5
6
7
8
9
10
11
val array = arrayOf(100, 200)
// 0부터 마지막 index 까지 반복
for (i in array.indices){
println("순번 : ${i} / 값 : ${array[i]}")
}
// withIndex를 활용해 index 와 value 를 한번에 가져올 수 있다.
for ((index, value) in array.withIndex()){
println("순번 : ${index} / 값 : ${value}")
}
Kotlin의 컬렉션 - List, Set, Map
불변
,가변
을 꼭 지정해 주어야 한다.
Kotlin의 계층 구조
- 가변(mutable) 클래스 :
element
를 삭제, 추가가능
- 불변 클래스 :
element
를 삭제, 추가불가
- Java로 예를 들면 ->
Collections.unmodifiableList()
를 붙인 것과 같다. - 불변이라도
reference Type
인Element
필드는 수정 가능 - ex). 원래 존재하는 값을 수정을 할 수 있다.
- 단, 값을 추가, 삭제는 불가능
- Java로 예를 들면 ->
Kotlin은 불변/가변을 지정해 주어야 한다는 사실을 꼭 기억해야 한다.
List
Java의 List
1
final List<Integer> numbers = Arrays.asList(100, 200);
Kotlin의 List
1
2
3
4
5
// List
val numbers = listOf(100, 200)
// 비어 있는 리스트의 타입은 명시적으로 적어야 한다.
val emptyList = emptyList<Int>()
listOf()
를 통해불변 리스트
를 만든다.emptyList<Type>()
를 통해 비어 있는 리스트를 만든다.
1
2
3
4
5
fun main() {
printNumbers(emptyList())
}
private fun printNumbers(numbers: List<Int>){}
- 위와 같이
Type
을 추론할 수 있다면 타입을 생략할 수 있다.
Java의 for문
1
2
3
4
5
6
7
8
9
10
11
12
// 하나 가져오기
System.out.println(numbers.get(0));
// For Each
for(int number : numbers){
System.out.println(number);
}
// 전통적인 For문
for(int i = 0; i < numbers.size(); i++){
System.out.printf("%s %s", i, numbers.get(i));
}
Kotlin의 for문
1
2
3
4
5
6
7
8
9
10
11
12
// 배열처럼 대괄호로 가져올 수 있다.
println(numbers[0])
// for each문
for (number in numbers){
println(number)
}
// for withIndex() -> key, value 를 같이 가져올 수 있다.
for ((idx, value) in numbers.withIndex()) {
println("${idx} ${value}")
}
가변(Mutable) 리스트를 만들고 싶다면?
1
2
3
// 가변 List
val numbersV2 = mutableListOf(400, 600)
numbersV2.add(300)
우선 불변 리스트로 만들고 필요한 경우만 가변 리스트로 바꾸자!!
Set (집합)
- 집합은
List
와 다르게 순서가 없고 같은element
는 하나만 존재 가능 자료구조적 의미
만 제외하면 모든 기능이List
와 비슷하다.
Kotlin의 Set
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// Set
val setNumbers = setOf(100, 200)
// for each
for(number in setNumbers) {
println(number)
}
// for withIndex()
for ((index, value) in setNumbers.withIndex()) {
println("$index $value")
}
// Set의 가변(Mutable)
// 기본 구현체는 LinkedHashSet
val setNumbersV2 = mutableSetOf(400, 600)
Map
Java의 Map
1
2
3
4
5
6
7
// JDK 8까지
Map<Integer, String> map = new HashMap<>();
map.put(1, "MONDAY");
map.put(2, "TUESDAY");
// JDK 9부터
Map.of(3, "WEDNESDAY", 4, "THURSDAY");
Kotlin의 Map
1
2
3
4
5
6
val oldMap = mutableMapOf<Int, String>()
oldMap[1] = "MONDAY"
oldMap[2] = "TUESDAY"
// mapOf 를 사용하는 경우는 key, value 사이에 to 를 넣어야 한다.
mapOf(3 to "WEDNESDAY", 4 to "THURSDAY")
- Kotlin도 동일하게
MutableMap
을 만들어 넣을 수도 있고, 정적 팩토리 메소드를 바로 활용할 수도 있다. mutableMapOf
에서Type
을 추론할 수 있도록Type
을 지정- 가변
Map
이기 때문에 Java와 같이put
을 사용해도 되고,map[key] = value
를 사용해도 된다. mapOf
를 사용해서key to value
를 사용해서 불변map
을 만들수 있다.
- 가변
Map의 반복문
Java에서 Map 반복문
1
2
3
4
5
6
7
8
9
10
11
// Key를 가져와서 반복하는 방법
for(int key : map.keySet()){
System.out.println(key);
System.out.println(map.get(key));
}
// Entry라는 Key와 Value가 함께들어 있는 객체를 반복하는 방법
for(Map.Entry<Integer, String> entry : map.entrySet()){
System.out.println(entry.getKey());
System.out.println(entry.getValue());
}
Kotlin에서 Map 반복문
1
2
3
4
5
6
7
8
9
10
11
// Key를 가져와서 반복하는 방법
for (key in oldMap.keys) {
println(key)
println(oldMap[key])
}
// entries라는 프로퍼티스를 사용해서 Key와 Value를 사용하는 방법
for ((key, value) in oldMap.entries) {
println(key)
println(value)
}
컬렉션의 null 가능성 / Java와 함께 사용
?의 위치에 따라서 미묘하게 null 가능성이 바뀐다.
List
: `List`에 `null`이 들어갈 수 있지만, `List`는 절대 `null`이 아님 List
? : `List`에는 `null`이 들어갈 수 없지만, `List`는 `null`일 수 있음 List<Int?>? :
List
에null
이 들어갈 수도 있고,List
가null
일 수도 있음
Java는 읽기 전용 컬렉션과 변경 가능 컬렉션을 구분하지 않는다.
Kotlin
의 불변 리스트를Java
에서 가져오는 경우,Java
에서는 불변인지 모르기 때문에Element
를 추가할 수 있다.- 이후에
Kotlin
으로 돌려주면 불변 리스트에Element
가 추가되어오동작
할수 있다.
Java는 nullable 타입과 non-nullable 타입을 구분하지 않는다.
Kotlin
의non-nullable
리스트를Java
에서 가져오는 경우Java
에서는non-nullable
를 모르기 때문에null
을 추가할 수 있다.- 이후에
Kotlin
으로 돌려주면non-nullable
에null
이 추가되어오동작
할수 있다.
결국 Kotlin 쪽의 컬렉션이 Java에서 호출되면 컬렉션 내용이 변할 수 있음을 감안해야 한다.
Kotlin
쪽에서Collections.unmodifableXXX()
를 활용하면 변경 자체를 막을 수 있다.
Kotlin에서 Java 컬렉션을 가져다 사용할 때는 플랫폼 타입을 신경써야 한다.
Java
에서List<Integer>
를Kotlin
에 보내면List<Int?>
/List<Int>?
/List<Int?>?
인지 알수 없다.Java
코드를 보며, 맥락을 확인하고Java
코드를 가져오는 지점을wrapping
한다.
이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.