알고리즘 풀때 스트링을 자주쓰는 편인데 코틀린 String에 대해 잘 안나와 있어 코틀린 사이트에서 추려서 정리해봤다

앞 뒤문자를 짜르는 명령어가 필요했는데 결국 substring을 이용해서 만들었다고 한다.

drop 은 문자열의 앞이나 뒷부분을 자를 때 사용된다.

내부적으로는 substring 으로 구현되어 있다.

  • drop : 앞에서부터 n 개의 문자를 제거한 String 을 반환
  • dropLast: 뒤에서부터 n 개의 문자를 제거
  • dropWhile, dropLastWhile: 조건을 만족하지 않는 문자가 나올때까지 제거
  • 파이썬같이 insert나 append를 찾고 싶었어나 배열은 자료구조상 안된 arrayList에서는 가능한것 같음.
val length: Int, length : Returns the length of this character sequence.
fun compareTo(other: String): Int compare() : 스트링을 비교해서 같으면 0 다르면 차이를 int로 리턴
fun equals(other: Any?): Boolean equals(): 스트링을 비교해서 같으면 true 리턴
fun get(index: Int): Char get(idx): 지정된 index의 문자를 리턴
fun hashCode(): Int hashCode() 문자열의 해시코드를 생성
operator fun plus(other: Any?): String 2개의 스트링을 합쳐주는 연산자
fun subSequence(start: Int, end: Int): CharSequence 지정된 범위의 Char Sequence를 리턴
fun toString(): String 스트링을 리턴 ?
val String.cstr: CValues<ByteVar>  
val CharSequence.indices: IntRange Returns the range of valid character indices for this char sequence.
val CharSequence.lastIndex: Int 스트링의 마지막 문자의 인덱스를 리턴 비었으면 -1 리턴
val String.utf16: CValues<UShortVar> utf8 utf16 utf32등도 있다.
val String.wcstr: CValues<UShortVar>  
fun CharSequence.all(predicate: (Char) -> Boolean): Boolean Returns true if all characters match the given predicate.
fun CharSequence.any(): Boolean Returns true if char sequence has at least one character.
fun CharSequence.asIterable(): Iterable<Char> Creates an Iterable instance that wraps the original char sequence returning its characters when being iterated.
fun CharSequence.asSequence(): Sequence<Char> Creates a Sequence instance that wraps the original char sequence returning its characters when being iterated.
fun <K, V> CharSequence.associate(
    transform: (Char) -> Pair<K, V>
): Map<K, V>
associate
Returns a Map containing key-value pairs provided by transform function applied to characters of the given char sequence.
fun String.capitalize(locale: Locale): String  
fun String.decapitalize(locale: Locale): String  
fun CharSequence.chunked(size: Int): List<String> 지정된 사이즈로 문자시퀀스를 짤라 리스트를 만든다.
operator fun CharSequence.contains(
    other: CharSequence,
    ignoreCase: Boolean = false
): Boolean
문자열이 자신에게 포함되어 있는지
fun CharSequence.count(): Int 스트링길이
fun String.drop(n: Int): String 앞 문자를 n개 지운 스트링을 리턴한다
fun String.dropLast(n: Int): String 마지막 문자부터 n개 지운 스트링을 리턴한다.
fun String.dropWhile(predicate: (Char) -> Boolean): String 앞에서 부터 조건대로 문자를 제거
fun String.dropLastWhile(
    predicate: (Char) -> Boolean
): String
뒤에서 부터 조건대로 문자를 제거
val string = "<<<First Grade>>>"
println(string.drop(6)) // st Grade>>>
println(string.dropLast(6)) // <<<First Gr
println(string.dropWhile { !it.isLetter() }) // First Grade>>>, 앞쪽 문자가 아닌걸 제거
println(string.dropLastWhile { !it.isLetter() }) // <<<First Grade, 뒤쪽 문자가 아닌걸 제거
fun String.filter(predicate: (Char) -> Boolean): String Returns a string containing only those characters from the original string that match the given predicate.
fun String.filterIndexed(
    predicate: (index: Int, Char) -> Boolean
): String
Returns a string containing only those characters from the original string that match the given predicate.
fun String.filterNot(predicate: (Char) -> Boolean): String Returns a string containing only those characters from the original string that do not match the given predicate.
fun CharSequence.find(predicate: (Char) -> Boolean): Char? find: Returns the first character matching the given predicate, or null if no such character was found.
fun CharSequence.first(): Char Returns the first character.
fun CharSequence.firstOrNull(): Char? Returns the first character, or null if the char sequence is empty.
fun CharSequence.isEmpty(): Boolean Returns true if this char sequence is empty (contains no characters).
operator fun CharSequence.iterator(): CharIterator Iterator for characters of the given char sequence.
fun CharSequence.lines(): List<String> Splits this char sequence to a list of lines delimited by any of the following character sequences: CRLF, LF or CR.
fun <R> CharSequence.map(transform: (Char) -> R): List<R> map: Returns a list containing the results of applying the given transform function to each character in the original char sequence.
fun <R : Comparable<R>> any_iterable<R>.maxOf(selector: (Char) -> R maxOf: Returns the largest value among all values produced by selector function applied to each character in the char sequence.
fun <R : Comparable<R>> any_iterable<R>.minOf(selector: (Char) -> R minOf: Returns the smallest value among all values produced by selector function applied to each character in the char sequence.

끝이 없다. 더 보고 싶은 분은 아래 코틀린 사이트에서 공부하시길

 

 

 

https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-string/

 

String - Kotlin Programming Language

 

kotlinlang.org

 

'Kotlin > String' 카테고리의 다른 글

CharSequence  (0) 2022.09.13
문자열 클래스 String, StringBuffer, StringBuilder  (1) 2022.09.13
StringBuilder  (0) 2022.09.13

1. Collection Sort

Kotlin 에서는 Collection 을 정렬하기 위한 여러가지 유틸리티들을 제공합니다.

 

1.1. Sort, Sorted

가장 쉬운 방법은 sort 메소드를 호출하는 겁니다.

기본적으로 오름차순으로 정렬합니다.

val list = mutableListOf(1, 2, 7, 6, 5, 6)
list.sort()
println(list)  // [1, 2, 5, 6, 6, 7]

 

sort 메소드는 해당 Collection 의 원소 위치가 변경됩니다.

기존 Collection 은 그대로 둔 채 새로운 Collection 으로 받길 원한다면 sorted 메소드를 사용해야 합니다.

sorted 메소드를 사용하면 기존 Collection 은 변하지 않습니다.

val list = mutableListOf(1, 2, 7, 6, 5, 6)  //뮤터블 리스트 초기화 생성
val sorted = list.sorted()  //소팅해서 새로운 리슽 생성
println(sorted)  // [1, 2, 5, 6, 6, 7]  /소팅되었음
println(list)    // [1, 2, 7, 6, 5, 6] (sorted 를 사용했기 때문에 변하지 않음)

 

내림차순으로 정렬하고 싶다면 sortByDescending 를 사용하거나 reverse 메소드를 사용하면 됩니다.

마찬가지로 sortedByDescending 를 사용하면 원래 Collection 의 변경 없이 내림차순으로 정렬된 값을 구할 수 있습니다.

// 1. sortByDescending 로 내림차순 정렬
list.sortByDescending { it }

val sorted = list.sortedByDescending { it }  //내림차순 정열

// 2. reverse 사용해서 정렬 후 뒤집기
list.sort()  //자신을 소팅한후
list.reverse()  //순서를 바꾼다.

val sorted = list.sorted().reversed()   //.연산자를 이용 한번에 붙여써도

 

1.2. SortBy

만약 Object 의 특정 Property 들을 기준으로 정렬하고 싶다면 sortBy 메소드를 사용하면 됩니다.

sortBy 메소드는 Object 를 받아서 Property 를 반환하는 Lamdba 식을 파라미터로 받습니다.

val list = mutableListOf(1 to "a", 2 to "b", 7 to "c", 6 to "d", 5 to "c", 6 to "e")
list.sortBy { it.second }
println(list)  // [(1, a), (2, b), (7, c), (5, c), (6, d), (6, e)]

sort 와 마찬가지로 기존 Collection 의 변경 없이 정렬된 값을 받고 싶다면 sortedBy 를 사용하면 됩니다.

그리고 내림차순을 지원하는 sortByDescending 도 있습니다.

 

1.3. SortWith

sortWith 메소드를 사용하면 여러 가지 조건을 섞어서 정렬할 수 있습니다.

sortWith 메소드는 Comparator 를 파라미터로 받습니다.

(Kotlin 에서 Comparator 를 생성하는 여러가지 방법은 다음 챕터에서 다룹니다)

val list = mutableListOf(1 to "a", 2 to "b", 7 to "c", 6 to "d", 5 to "c", 6 to "e")
list.sortWith(compareBy({it.second}, {it.first}))
println(list)  // [(1, a), (2, b), (5, c), (7, c), (6, d), (6, e)]

 

위 Collection 은 it.second(문자) 로 먼저 정렬된 후에 it.first(숫자) 로 정렬됩니다.

그리고 역시 sortedWith 메소드가 존재하며, 역순으로 정렬할때는 reverse 를 사용하거나 Comparator 를 반대로 수정하면 됩니다.

 

2. Comparison

Kotlin 은 Comparator 를 만들기 위해 kotlin.comparisons 라는 유용한 패키지를 제공합니다.

이 챕터에서는 아래 컨텐츠를 다룹니다.

  • Comparator creation
  • Handling of null values
  • Comparator rules extension

 

2.1. Comparator Creation

Kotlin 은 Comparator 를 생성하는 여러 팩토리 메서드를 제공합니다.

 

2.1.1. naturalOrder

가장 간단한 생성 메서드는 naturalOrder() 입니다.

아무런 파라미터를 필요로 하지 않으며 오름차순을 기본으로 합니다.

val ascComparator = naturalOrder<Long>()

 

2.1.2. compareBy

여러 개의 속성을 사용하고 싶다면 compareBy 메소드를 사용하면 됩니다.

파라미터로는 Comparable 를 리턴하는 정렬 규칙을 여러 개 사용할 수 있습니다.

그럼 넘겨진 규칙들은 순차적으로 호출 되며 원소들을 정렬합니다.

만약 먼저 나온 규칙에서 원소의 우열이 가려져 정렬 처리가 되었다면 뒤의 규칙들은 확인하지 않습니다.

val complexComparator = compareBy<Pair<Int, String?>>({it.first}, {it.second})

위 코드에서 it.first 값을 사용해 먼저 비교를 하고 값이 같은 경우에만 it.second 비교까지 이루어집니다.

 

2.1.3. Comparator

간단하게 new Comparator 를 선언해서 만들 수도 있습니다.

자바와 마찬가지로 두 원소에 대한 비교 조건을 넣어줘야 합니다.

val caomparator = Comparator<Int> { a, b -> a.compareTo(b) }

 

2.2. Handling of null Values

정렬하려는 Collection 이 null 값을 갖고 있을 수도 있습니다.

nullsFirst 또는 nullsLast 와 함께 Comparator 를 사용하면 null 값을 가장 처음 또는 가장 마지막에 위치하도록 설정할 수 있습니다.

val list = mutableListOf(4, null, 1, -2, 3)

list.sortWith(nullsFirst())  // [null, -2, 1, 3, 4]

list.sortWith(nullsLast())  // [-2, 1, 3, 4, null]

list.sortWith(nullsFirst(reverseOrder()))  // [null, 4, 3, 1, -2]

list.sortWith(nullsLast(compareBy { it }))  // [-2, 1, 3, 4, null]

 

2.3. Comparator Rules Extension

Comparator 오브젝트는 추가적인 정렬 규칙과 혼합되거나 확장할 수 있습니다.

kotlin.comparable 패키지에 있는 then 키워드를 활용하면 됩니다.

첫 번째 비교의 결과가 동일할 때만 두번째 비교가 이루어집니다.

val students = mutableListOf(21 to "Helen", 21 to "Tom", 20 to "Jim")

val ageComparator = compareBy<Pair<Int, String?>> {it.first}
val ageAndNameComparator = ageComparator.thenByDescending {it.second}

// [(20, Jim), (21, Tom), (21, Helen)]
println(students.sortedWith(ageAndNameComparator))

위 코드는 나이가 어린 순으로 먼저 정렬하고 나이가 같으면 이름을 알파벳 역순으로 정렬합니다.

 

Reference

'Kotlin > Collection' 카테고리의 다른 글

Collection List, Set, Map  (0) 2022.09.12

Collection

Collection(콜렉션)은 대부분의 프로그래밍 언어에 있는 자료구조입니다. 자바의 List, Map, Set 등을 Collection이라고 합니다. Collection은 Generic으로 구현이 되어 다양한 타입과 함께 사용될 수 있습니다.

코틀린의 Collection은 기본적으로 코트린의 다른 자료구조와 마찬가지로 Mutable(변할 수 없는)과 Immutable(불변의)을 별개로 지원합니다. Mutable로 생성하면 추가, 삭제가 가능하지만, Immutable로 생성하면 수정이 안됩니다.

코틀린의 콜렉션들은 아래 그림과 같은 상속 구조 갖고 있습니다.

(출처: kotlinlang.com)

// Collection 인터페이스
val list: Collection<Int> = listOf(18, 1, 1, 4)  //초기화와 함께 선언
println(list.size) // 4
println(list.isEmpty()) // false (isNotEmpty, none도 있음)
println(18 in list) // true

// MutableCollection 인터페이스
val mutableList: MutableCollection<Int> = mutableListOf(1, 2, 4, 2, 3, 2, 5) // arrayListOf와 동일
mutableList.add(1) 
println(mutableList) // [1, 2, 4, 2, 3, 2, 5, 1]
mutableList.addAll(listOf(3, 2, 4))
println(mutableList) // [1, 2, 4, 2, 3, 2, 5, 1, 3, 2, 4]
mutableList.remove(1)
println(mutableList) // [2, 4, 2, 3, 2, 5, 1, 3, 2, 4]
mutableList.removeAll(listOf(1, 2))
println(mutableList) // [4, 3, 5, 3, 4]
mutableList.retainAll(listOf(3, 5))
println(mutableList) // [3, 5, 3]
mutableList.clear() 
println(mutableList) // []

Collection 반복

val fruits = listOf("apple", "banana", "kiwi")  //리스트 생성
for (item in fruits) {   //리스트 반복하기
  println(item)
}
// 요소의 인덱스를 통해 List에 접근하기
for (index in fruits.indices) {   // 인덱스 지정
  println("fruits[$index] = ${fruits[index]}")   //[]연산자 이용 인덱스 접근
}
// while 루프 이용하기
var index = 0
while (index < fruits.size) {
  println("fruits[$index] = ${fruits[index]}")
  index++
}

 

emptyList() / listOfNotNull() 함수

비어 있는 리스트를 생성하려면 emptyList<>()를 사용할 수 있습니다. 이때는 반드시 형식 매개변수를 지정합니다. listOfNotNull()로 초기화하면 null을 제외한 요소만 반환해 List를 구성할 수 있습니다.

val emptyList: List<String> = emptyList<String>()  // 빈리스트 생성
val nonNullsList: List<Int> = listOfNotNull(2, 45, 2, null, 5, null)  //Null을 제외한 리스트
println(nonNullsList) // [2, 45, 2, 5]

 

List

List는 데이터가 저장하거나 삭제될 때 순서를 지키는 Collection입니다. List는 Mutable(변할 수 없는)과 Immutable(불변의)을 모두 지원합니다.
이 타입의 구현체는 ArrayList, LinkedList 두 가지가 있다 

// List 인터페이스 
val list: List<Double> = listOf(20.18, 1.14, 9.15, 1.14) // 불변형
val list2: List<Double> = mutableListOf(20.18, 1.14, 9.15, 1.14) // 가변형 

val list3: List<Int> = LinkedList<Int>()   //LinkedList와
val list4: List<Int> = ArrayList<Int>()     // ArrayList 2가지가 있다.

println(list[0]) // 20.18
println(list.indexOf(1.14)) // 1
println(list.indexOf(9.31)) // -1
println(list.lastIndexOf(1.14)) // 3
println(list.subList(0, 3)) // [20.18, 1.14, 9.15]

println(list.size) // List 크기
println(list.get(0)) // 해당 인덱스의 요소 가져오기
println(list.contains(2.0)) // 포함 여부 확인하기


List 인터페이스에는 indices()(인덱스의 범위), contains(), get()/elementAt()(해당 인덱스의 요소를 읽기), last(), first(), firstOrNull, lastOrNull, count(), distinct(), joinToString()(요소들의 값을 문자열로 변환하여 결합), single(요소 하나 반환), singleOrNull, binarySearch, find 등이 있다

이외에도 MutableList 인터페이스에는 slice(), containsAll(), asReversed()(모든 요소를 역순으로 저장한 새로운 List를 생성), toList(), toMutableList(), toSet(), toMutableSet(), toHashSet() 등이 있다
LinkedList에서만 사용할 수 있는 함수들은 addFirst(), addLast(), removeFirst(), removeLast() 등이 있다
그 외에도 max(), min() 등의 함수가 존재한다

List : Immutable

listOf<타입>(아이템, )로 Immutable List를 생성 및 초기화를 할 수 있습니다. 코틀린은 아이템의 타입을 추론하기 때문에 타입을 생략해도 됩니다. Immutable이기 때문에 get만 가능합니다. List의 getter는 자바처럼 get(index)도 지원하고 배열처럼 [index]도 지원합니다. 코틀린은 간결하고 직관적인 배열같은 표현 방식을 선호합니다.

val fruits= listOf<String>("apple", "banana", "kiwi", "peach")
// val fruits= listOf("apple", "banana", "kiwi", "peach") -> 타입 생략 가능
println("fruits.size: ${fruits.size}")
println("fruits.get(2): ${fruits.get(2)}")
println("fruits[3]: ${fruits[3]}")
println("fruits.indexOf(\"peach\"): ${fruits.indexOf("peach")}")

위의 코드를 실행한 결과입니다.

fruits.size: 4
fruits.get(2): kiwi
fruits[3]: peach
fruits.indexOf("peach"): 3

 

List : Mutable

수정가능한 List는 mutableListOf로 선언합니다. listOf와 대부분 비슷하지만, 추가 및 삭제가 가능합니다. 자바의 Collection에 익숙하시다면 remove, add, addAll, removeAt 등은 이미 알고 계실 것입니다. 또 slice(), containsAll(), asReversed()(모든 요소를 역순으로 저장한 새로운 List를 생성), toList(), toMutableList(), toSet(), toMutableSet(), toHashSet() 등이 있다
LinkedList에서만 사용할 수 있는 함수들은 addFirst(), addLast(), removeFirst(), removeLast() 등이 있다
그 외에도 max(), min() 등의 함수가 존재한다

val fruits= mutableListOf<String>("apple", "banana", "kiwi", "peach")
fruits.remove("apple")
fruits.add("grape")
println("fruits: $fruits")

fruits.addAll(listOf("melon", "cherry"))
println("fruits: $fruits")
fruits.removeAt(3)
println("fruits: $fruits")

위의 코드를 실행한 결과입니다.

fruits: [banana, kiwi, peach, grape]
fruits: [banana, kiwi, peach, grape, melon, cherry]
fruits: [banana, kiwi, peach, melon, cherry]

그 외에도 replace, replaceAll, contains, forEach 등의 메소드도 지원합니다.

불변형 List를 가변형으로 변환하기

// 불변형 List를 가변형으로 변환하기
val names: List<String> = listOf("one", "two", "three") // 불변형 List

val mutableNames = names.toMutableList()  // 새로운 가변형 List 가 만들어짐
mutableNames.add("four")
println(mutableNames)
// [one, two, three, four]

Set

Set은 동일한 아이템이 없는 Collection입니다. Set의 아이템들의 순서는 특별히 정해져 있지 않습니다. Set은 null 객체를 갖고 있을 수 있습니다. 동일한 객체는 추가될 수 없기 때문에 null도 1개만 갖고 있을 수 있습니다. List와 같이 Set도 Immutable과 Mutable을 별개로 지원합니다.  이 타입의 구현체는 HashSet, LinkedHashSet, TreeSet 세 가지가 있다 

Set : Immutable

setOf<타입>(아이템들)로 객체를 생성할 수 있습니다. 다음과 같이 객체 아이템들을 확인할 수 있습니다.

val numbers = setOf<Int>(33, 22, 11, 1, 22, 3)
println(numbers)
println("numbers.size: ${numbers.size}")
println("numbers.contains(1): ${numbers.contains(1)}")
println("numbers.isEmpty(): ${numbers.isEmpty()}")

실행 결과입니다.

[33, 22, 11, 1, 3]
numbers.size: 5
numbers.contains(1): true
numbers.isEmpty(): false

forEach 또는 Iterator 등으로 모든 객체를 탐색할 수도 있습니다.

Set : Mutable

Mutable은 mutableSetOf<타입>(아이템들) 로 생성할 수 있습니다. Mutable이기 때문에 추가, 삭제가 가능합니다. List와 비슷한 메소드들을 지원합니다.

val numbers = mutableSetOf<Int>(33, 22, 11, 1, 22, 3)
println(numbers)
numbers.add(100)
numbers.remove(33)
println(numbers)
numbers.removeIf({ it < 10 }) // 10 이하의 숫자를 삭제
println(numbers)

실행 결과 입니다.

[33, 22, 11, 1, 3]
[22, 11, 1, 3, 100]
[22, 11, 100]

sortedSetOf() 함수 / linkedSetOf() 함수

sortedSetOf() 함수는 자바의 TreeSet 컬렉션을 정렬된 상태로 반환합니다. 이 함수를 사용하려면 java.util.* 패키지를 임포트해야 합니다. TreeSet는 저장된 데이터의 값에 따라 정렬되는데, 일종의 개선된 이진 탐색 트리(Binary-search Tree)인 레드 블랙 트리(RB tree: Red-Black tree) 알고리즘을 사용해 자료구조를 구성합니다. HashSet보다 성능이 좀 떨어지고 데이터를 추가하거나 삭제하는 데 시간이 걸리지만 검색과 정렬이 뛰어나다는 장점이 있습니다.

linkedSetOf()는 자바의 LinkedHashSet 자료형을 반환하는 헬퍼 함수입니다. 링크드 리스트를 사용해 구현된 해시 테이블에 요소를 저장합니다. HashSet, TreeSet보다 느리지만 데이터를 가리키는 포인터 연결을 통해 메모리 저장 공간을 좀 더 효율적으로 사용할 수 있습니다.

import java.util.*

// 자바의 java.util.TreeSet 선언
val intsSortedSet: TreeSet<Int> = sortedSetOf(4, 1, 7, 2)
intsSortedSet.add(6)
intsSortedSet.remove(1)
println("intsSortedSet = ${intsSortedSet}")
intsSortedSet.clear()  // 모든 요소 삭제
println("intsSortedSet = ${intsSortedSet}")

// Linked List를 이용한 HashSet
val intsLinkedHashSet: java.util.LinkedHashSet<Int> = linkedSetOf(35, 21, 76, 26, 75)
intsLinkedHashSet.add(4)
intsLinkedHashSet.remove(21)

println("intsLinkedHashSet $intsLinkedHashSet")
intsLinkedHashSet.clear()
println(intsLinkedHashSet)

Map

Map은 key와 value를 짝지어 저장하는 Collection입니다. Map의 key는 유일하기 때문에 동일한 이름의 key는 허용되지 않습니다.에 Map 또한 Immutable과 Mutable을 별개로 지원합니다. 이 타입의 구현체는  HashMap,  LinkedHashMap, TreeMap 세 가지가 있다

// Map 인터페이스
val map: Map<String, String> = mapOf("Apple" to "사과", "Banana" to "바나나") // 불변형
println(map.size) // 2
println(map.keys) // [Apple, Banana]
println(map.values) // [사과, 바나나]
println(map.entries) // [Apple=사과, Banana=바나나]
println(map.containsKey("Cocoa")) // false
println(map.containsValue("바나나")) // true
println(map["Apple"]) // 사과
println(map.getOrDefault("Cocoa", "코코아")) // 코코아

// 맵 순회하기
for ((key, value) in map) {
  println("key=$key, value=$value")
}

// MutableMap 인터페이스
val map: MutableMap<String, String> = mutableMapOf() // 가변형 
println(map) // {}
println(map.put("Hi", "안녕1")) // null
println(map) // {Hi=안녕1}
map["Hi"] = "안녕2"
println(map) // {Hi=안녕2}
map.putAll(mapOf("How is it going?" to "잘 지내?", "Bye!" to "잘 가!"))
println(map) // {Hi=안녕2, How is it going?=잘 지내?, Bye!=잘 가!}
println(map.remove("Hi")) // 안녕2
println(map) // {How is it going?=잘 지내?, Bye!=잘 가!}
println(map.remove("Bye!", "잘 가!")) // true
println(map) // {How is it going?=잘 지내?}
map.clear()
println(map) {}

이외에도 getOrPut(k, v), toList(), toMutableMap(), toMap(), toSortedMap(), putAll() 등이 있다

Map의 기타 자료구조

앞에서 Set의 선언된 형태와 비슷하게 Map에서도 자바의 HashMap, SortedMap, LinkedHashMap을 사용할 수 있습니다

import java.util.*

// java.util.HashMap의 사용
val hashMap: HashMap<Int, String> = hashMapOf(1 to "Hello", 2 to "World")
println("hashMap = $hashMap")

// java.util.SortedMap 사용
val sortedMap: SortedMap<Int, String> = sortedMapOf(1 to "Apple", 2 to "Banana")
println("sortedMap = $sortedMap")

// java.util.LinkedHashMap의 사용
val linkedHash: LinkedHashMap<Int, String> = linkedMapOf(1 to "Computer", 2 to "Mouse")
println("linkedHash = $linkedHash")

Map : Immutable

Map은 mapOf<key type, value type>(아이템)로 생성할 수 있습니다. 아이템은 Pair객체로 표현하며, Pair에 key와 value를 넣을 수 있습니다. Pair(A, B)는 A to B로 간단히 표현이 가능합니다. 이런 문법이 가능한 것은 to가 Infix이기 때문입니다.

val numbersMap = mapOf<String, String>(
    "1" to "one", "2" to "two", "3" to "three")
println("numbersMap: $numbersMap")
val numbersMap2 = mapOf(Pair("1", "one"), Pair("2", "two"), Pair("3", "three"))
println("numbersMap2: $numbersMap2")

// 실행해보면 모두 동일한 값을 갖고 있습니다.
// numbersMap: {1=one, 2=two, 3=three}
// numbersMap2: {1=one, 2=two, 3=three}

Map의 데이터를 읽는 것도 다른 Collection과 유사합니다. getter는 get(index)와 [index]를 모두 지원합니다. 코틀린은 배열 방식을 선호합니다. keys와 values는 key와 value만으로 구성된 Set을 리턴해줍니다.

val numbersMap = mapOf<String, String>(
    "1" to "one", "2" to "two", "3" to "three")
println("numbersMap.get(\"1\"): ${numbersMap.get("1")}")
println("numbersMap[\"1\"]: ${numbersMap["1"]}")
println("numbersMap[\"1\"]: ${numbersMap.values}")
println("numbersMap keys:${numbersMap.keys}")
println("numbersMap values:${numbersMap.values}")

for (value in numbersMap.values) {
    println(value)
}

실행 결과입니다.

numbersMap.get("1"): one
numbersMap["1"]: one
numbersMap["1"]: [one, two, three]
numbersMap keys:[1, 2, 3]
numbersMap values:[one, two, three]
one
two
three

Map : Mutable

Mutable은 mutableMapOf<key type, value type>(아이템)로 생성합니다. 객체 추가는 put 메소드이며, Pair를 사용하지 말고 인자로 key와 value를 넣어주면 됩니다. put도 배열 방식을 지원합니다. 그 외에 자바의 Map과 유사합니다.

val numbersMap = mutableMapOf<String, String>(
        "1" to "one", "2" to "two", "3" to "three")
println("numbersMap: $numbersMap")

numbersMap.put("4", "four")
numbersMap["5"] = "five"
println("numbersMap: $numbersMap")

numbersMap.remove("1")
println("numbersMap: $numbersMap")

numbersMap.clear()
println("numbersMap: $numbersMap")

실행 결과 입니다.

numbersMap: {1=one, 2=two, 3=three}
numbersMap: {1=one, 2=two, 3=three, 4=four, 5=five}
numbersMap: {2=two, 3=three, 4=four, 5=five}
numbersMap: {}

Collection 상속

List와 Set은 Collection을 상속합니다. 이 클래스들은 Collection에 대입할 수 있기 때문에 아래와 같이 사용할 수 있습니다.

fun printAll(strings: Collection<String>) {
    for(s in strings) print("$s ")
    println()
}

val stringList = listOf("one", "two", "one")
printAll(stringList)

val stringSet = setOf("one", "two", "three")
printAll(stringSet)

실행 결과 입니다.

one two one
one two three

컬렉션 선택하기

List 인터페이스의 ArrayList와 LinkedList는 기본적으로는 무작위나 순차적인 처리 속도가 더 빠른 ArrayList를 선택하는 것이 좋다. 그러나 List의 중간에서 추가나 삭제를 자주 한다면 LinkedList를 사용하는 것이 좋다. 물론, 정해진 수의 요소들을 처리할 때는 배열을 사용하는 게 좋다
Set 인터페이스에는 LinkedHashSet, HashSet, TreeSet이 있다. 기본적으로는 코클린에서 생성 시 제공되는 LinkedHashSet을 사용하는 것이 좋으며, 무작위 검색의 성능이 매우 중요하다면 HashSet을, 그리고 요소의 일정한 순서 유지와 처리가 중요하다면 TreeSet을 사용하는 것이 좋다
Map 인터페이스는 LinkedHashMap, HashMap, TreeMap이 있다. 코틀린은 기본적으로 LinkedHashMap을 사용한다. HashMap은 무작위 검색 시에만 조금 더 유리하며, 정렬된 상태로 요소를 유지할 필요가 있을 때만 TreeMap을 사용하는 게 좋다. 그리고 Map은 크기가 성능을 좌우하므로 할당된 크기에 너무 많은 요소가 저장되지 않도록 하는 것이 중요하다

 정렬

정렬에는 sorted(), sortedBy(), sortedDescending(), sortedDescendingBy()가 있다

정리

코틀린의 Collection인 Map, Set, List에 대해서 알아보았습니다. 자바와 다른 것은 Mutable과 Immutable을 구분하여 지원한다는 점입니다. 그 외의 지원하는 메소드는 자바와 거의 유사합니다.

 

'Kotlin > Collection' 카테고리의 다른 글

Collection Sort  (0) 2022.09.12

+ Recent posts