다재다능 코틀린 프로그래밍 책으로 코틀린 스터디를 진행하면서 발표를 위해 준비했던 글입니다.
콜렉션의 특징
- Java의 뮤터블 콜렉션 인터페이스는 코틀린에서 이뮤터블 읽기전용 인터페이스와 뮤터블 읽기 - 쓰기 인터페이스 2개의 인터페이스로 나뉘어 졌다.
- JDK 제공 함수 이외에 몇 가지 편리한 메소드를 제공한다.
코틀린이 제공하는 편리한 메소드들
- withIndex()
val names = listOf("Tom", "Jerry")
println(names.javaClass)
for ((index, value) in names.withIndex()) {
println("$index $value")
}
// ...ArrayList
// 0 Tom
// 1 Jerry
페어와 트리플 사용하기
println(Pair("Tom", "Jerry")) // (Tom, Jerry)
println(mapOf("Tom" to "Cat", "Jerry" to "Mouse")) // {Tom=Cat, Jerry=Mouse}
- to() 확장 함수는 코틀린의 모든 객체에서 사용이 가능하며 Pair 인스턴스를 만든다.
val airportCodes = listOf("LAX", "SFO", "PDX", "SEA")
val temperatures =
airportCodes.map { code -> code to getTemperatureAtAirpot(code) }
for (temp in temperatures) {
println("Airport: ${temp.first}: Temperature: ${temp.second})
}
- airportCodes가 가지고있던 공항코드를 (코드, 온도) 꼴의 Pair로 도치시켰다.
- airportCodes는 List에서 List<Pair<String, String>>이 되었다.
- java였다면 Map을 만들거나 클래스를 새로 만드는 등 짐이 늘어났을 것이다. → 코드를 더 적게 사용하면서 타입 안정성을 가져갈 수 있다.
- Pair, Triple은 코틀린 스탠다드 라이브러리에 이 있는 하나의 클래스일 뿐이며 이뮤터블 하다.
- 만약 3개 이상의 값을 그룹핑하고 싶다면 데이터클래스를 만들어라. 7-5에서 다룰 예정
객체 배열과 프리미티브 배열
- Array 클래스는 코틀린의 배열을 상징
- 배열은 낮은 수준의 최적화가 필요할 때만 사용, 그 외에는 List 같은 자료구조를 사용하라.
- String 배열 만들기
val friends = arrayOf("Tintin", "Snowy")
println(friends::class) // class kotlin.Array
println(friends.javaClass) // ...String
println("${friends[0]} and ${friends[1]}") // Tintin and Snowy
- 인덱스 연산자인 []을 사용하면 get()메소드를 호출한다. 인덱스 연산자가 왼쪽에 있다면 set()메소드를 호출한다.
- 정수 배열 만들기
val numbers = arrayOf(1, 2, 3)
println(numbers::class) // class kotlin.Array
println(numbers.javaClass) // class [Ljava.lang.Integer;
- Wrapper 클래스로 박싱되면서 발생하는 오버헤드를 피하기 위해 intArrayOf() 같은 메소드를 사용하자.
- Java IntStrem이나 OptionalInt 랑 비슷한 이유
- Array 클래스에 함수들 사용해보기
val numbers = arrayOf(1, 2, 3)
println(numbers.size) // 3
println(numbers.average()) // 2.0
리스트 사용하기
- 이뮤터블 리스트는 listOf()로
- 뮤터블 리스트는 mutableListOf()로
- List에 접근할 시 []연산자 사용이 가능하다. get() 보다 노이즈가 적고 편리하다. [] 연산자를 사용하자.
- 콜렉션에 값이 있는지 없는지 확인하기 위해선 contains() 메소드나 in 연산자를 사용할 수 있다.
val fruits: List<String> = listOf("Apple", "Banana", "Grape")
println(frutis.contains("Apple") // true
println("Apple" in fruits) // true
- in 연산자가 더 표현력이 좋고 직관성 있다.
- kotlin.Collections.List 인터페이스는 Java의 Arrays.asList()로 만든 JDK 객체의 뷰로 동작 → 이뮤터블함
- 다른 element를 추가하고 싶다면 + 연산자를 사용할 수 있다.
val fruits: List<String> = listOf("Apple", "Banana", "Grape")
val fruits2 = fruits + "Orange"
println(fruits2) // [Apple, Banana, Grape, Orange]
- element를 제거하고 싶다면 - 연산자를 사용할 수 있다.
val fruits: List<String> = listOf("Apple", "Banana", "Grape")
val fruits2 = fruits - "Apple"
println(fruits2) // [Banana, Grape]
- 제거하려는 요소가 없다면 아무일도 일어나지 않는다.
- fruits의 인터페이스는 List이고 구현클래스는 JDK ArrayList이다.
- 충분한 의논이 끝난후에도 뮤터블 리스트가 만들고 싶다면 mutableListOf() 메소드를 사용해서 만들 수 있다.
- mutableListOf() 메소드 대신 arrayListOf() 함수를 사용해서 ArrayList의 참조를 직접 획득할 수도 있다.
셋 사용하기
- 이뮤터블 set은 setOf()로
- 뮤터블 set은 mutableSetOf()로
- HashSet은 hashSetOf()로
- LinkedHashSet은 linkedSetOf()로
- TreeSet은 sortedSetOf()로
- setOf()는 java.util.LinkedHashSet으로 취급된다.
맵 사용하기
- 이뮤터블 map은 mapOf()로
- 뮤터블 map은 mutableMapOf()로
- HashMap은 hashMapOf()로
- LinkedHashMap은 linkedMapOf()로
- SortedMap은 sortedMapOf()로
- 키-값 페어가 to() 확장 함수로 만들어지며 to() 확장함수는 코틀린의 모든 객체에서 사용 가능
- mapOf()는 Pair<K, V>를 인자로 취급
val cars = mapOf(1 to "K3", 2 to "K5");
val car: String = cars.get(3) // 오류
- Java와 다르게 존재하지 않는 key를 get할 때 동작하지 않는다.
- 아래와 같이 작성하면 nullable 타입을 리턴하며 정상적으로 동작하는데 6-2에서 설명 예정
val cars = mapOf(1 to "K3", 2 to "K5");
val car: String? = cars.get(3) // 정상 동작
- immutable 하더라도 참조하는 객체가 바뀔 수 있으므로 완전 thread-safe 하지는 않다?
'스터디 > 다재다능 코틀린 프로그래밍' 카테고리의 다른 글
7. 객체와 클래스 (0) | 2021.11.29 |
---|---|
6. 오류를 예방하는 타입 안전성 (0) | 2021.11.29 |
4. 외부 반복과 아규먼트 매칭 (0) | 2021.11.29 |
3. 함수를 사용하자. (0) | 2021.11.29 |
2. 코틀린 필수 사항 (0) | 2021.09.02 |